int T,n,a,b,c,d,m,st,ed,l,r;
int main() {
qr(T); for(int t=1;t<=T;t++) {
qr(n); qr(a); qr(b); qr(c); qr(d);
st=a-b; ed=a+b; l=c-d; r=c+d;
if(st*n>r||ed*n<l) {puts("NO"); continue;}
puts("YES");
}
return 0;
}
前綴和
int T,k,n,a[N],s[N],ans,pos;
int main() {
qr(T); while(T--) {
qr(n);qr(k);
for(int i=1;i<=n;i++)
qr(a[i]);
for(int i=2;i<n;i++) {
if(a[i-1]<a[i]&&a[i]>a[i+1]) s[i]=1;
else s[i]=0;
s[i]+=s[i-1];
}
pos=1;ans=0;
for(int i=1;i+k-1<=n;i++)
if(ans<s[i+k-2]-s[i]) ans=s[i+k-2]-s[i],pos=i;
pr1(ans+1); pr2(pos);
}
return 0;
}
一個合法的排列類似:
5 3 4 1 2
從1開始往右掃直到碰到第n+1個位置或者已經訪問過的位置,此時跳到應該掃描的位置並重復操作.
如上例:掃描1 2,掃描3 4,掃描5
如果不能掃描完全則輸出-1.
int T,n,a[N],ans,vis[N],num,p[N],now;
int main() {
qr(T); while(T--) {
qr(n); vis[n+1]=++num;
for(int i=1;i<=n;i++) qr(a[i]),p[a[i]]=i;
now=p[1]-1; ans=1;
for(int i=1;i<=n;i++)
if(p[i]==now+1) vis[p[i]]=num,now++;
else if(vis[now+1]==num) vis[now=p[i]]=num;
else {ans=0; break;}
puts(ans?"YES":"NO");
}
return 0;
}
考察簡單的DP+狀態壓縮.
設表示最大數的當前位選擇的數.
保障最大的措施是從後往前枚舉和數字從小到大枚舉.
int n,m,f[N][N],pre[N][N],a[N],cnt[N],num[11]={119,18,93,91,58,107,111,82,127,123,};
char s[N];
int g(char *s) {
int y=0;
for(int i=0;i<7;i++) y=y*2+(s[i]-'0');
return y;
}
bool pd(int x,int y) {return ((x&num[y])==x);}//x->y
int main() {
for(int i=1;i<=(1<<7);i++)cnt[i]=cnt[i&(i-1)]+1;
qr(n); qr(m); memset(f,-1,sizeof f);
for(int i=1;i<=n;i++) {
scanf("%s",s);
a[i]=g(s);
}
for(int i=0,j;i<=9;i++) if(pd(a[n],i)) f[n][cnt[num[i]^a[n]]]=i;
for(int i=n-1;i>0;i--) {
for(int j=0,k;j<=9;j++)
if(pd(a[i],j)) {
k=cnt[num[j]^a[i]];
for(int x=k;x<=m;x++)
if(f[i+1][x-k]!=-1) {
f[i][x]=j;
pre[i][x]=x-k;
}
}
}
if(f[1][m]==-1) puts("-1");
else {
int x=m;
for(int i=1;i<=n;i++)
qw(f[i][x]),x=pre[i][x];
}
return 0;
}
輪搜索即可.
複雜度大概爲
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=10010,G=1010;
int x[N],n,m,r,g,ans=2e9;
bool v[N][G];
vector<int> q[N];
void dfs(int now,int u,int t) {
if(u<1||u>m||t<0||v[u][t]) return ;
v[u][t]=1;
if(u==m) ans=min(ans,now*(g+r)+g-t);
if(!t) q[now+1].pb(u);
else {
dfs(now,u-1,t-(x[u]-x[u-1]));
dfs(now,u+1,t-(x[u+1]-x[u]));
}
}
void qr(int &x) {scanf("%d",&x);}
int main() {
qr(n); qr(m);
for(int i=1;i<=m;i++) qr(x[i]);
qr(g); qr(r);
sort(x+1,x+m+1); q[0].pb(1);
for(int i=0;i<=m;i++) {
for(int j:q[i]) dfs(i,j,g);
if(ans!=2e9) {printf("%d\n",ans); exit(0);}
}
puts("-1");
return 0;
}
#include<cstdio>
#include<vector>
#define pi pair<int,int>
using namespace std;
const int N=1e6+10;
vector<int>e[N];
int n,m,cnt,deg[N];
pi ans[N*3];
void dfs(int x,int t,int f) {
int fir=t;
ans[++cnt]=pi(x,t);
for(int y:e[x]) if(y^f) {
if(t==m) {
t=m-deg[x];
ans[++cnt]=pi(x,t);
}
dfs(y,++t,x);
ans[++cnt]=pi(x,t);
}
if(t!=fir-1&&x>1) ans[++cnt]=pi(x,fir-1);//保障回溯時爲fir-1
}
void add(int x,int y) {deg[x]++; e[x].push_back(y);}
int main() {
scanf("%d",&n);
for(int i=1,x,y;i<n;i++)
scanf("%d %d",&x,&y),add(x,y),add(y,x);
for(int i=1;i<=n;i++) m=max(m,deg[i]);//最大的t值顯然爲maxdeg
dfs(1,0,0);printf("%d\n",cnt);
for(int i=1;i<=cnt;i++) printf("%d %d\n",ans[i].first,ans[i].second);
return 0;
}
蠻有意思的題目.
簡明題意:三人圍剿入侵者.連通圖中每個點的度數<4,且每個環的長度<6.
顯然最後一個移動前大概爲這樣的情況.
然後,我就想不出來了.
只是覺得應該往靠近的方向跑.
看完題解後,發現這是個簡單的最短路.
把邊雙壓成一個點,就會形成一棵樹.
在n步範圍內一定可以追到.
於是可以得到這樣的代碼:
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5010;
int n,m,x,pos[3]={1,2,3},d[N][N];
vector<int> tmp(3),now(3),res(3),e[N];
void add(int x,int y) {e[x].push_back(y);}
int q[N];
void spfa(int *d,int st) {
int l=1,r=1; q[1]=st; d[st]=0;
while(l<=r) {
int x=q[l++];
for(int i=e[x].size()-1,y;i>=0;i--) {
y=e[x][i];
if(y^st&&!d[y])
d[y]=d[x]+1,q[++r]=y;
}
}
}
void get(int p,int x,int y,int z) {
now[0]=now[1]=now[2]=N;
for(int i=e[p].size()-1,t;i>=0;i--) {
t=e[p][i];
spfa(d[t],t);
}
for(int i=0,a;i<e[x].size();i++)
for(int j=0,b;j<e[y].size();j++) if((a=e[x][i])^(b=e[y][j]))
for(int k=0,c;k<e[z].size();k++) if(c=e[z][k],(a^c)&&(b^c)) {//模擬運動方向
res[0]=res[1]=res[2]=0;
for(int l=0,t;l<e[p].size();l++) {//模擬逃離方向
t=e[p][l];
tmp[0]=d[t][a];
tmp[1]=d[t][b];
tmp[2]=d[t][c];
sort(tmp.begin(),tmp.end());
res=max(res,tmp);//對方的去向不確定,所以我們應該取最大值
}
if(res<now) {
now=res;//追得更近了
pos[0]=a;
pos[1]=b;
pos[2]=c;
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) add(i,i);
for(int i=1,y;i<=m;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x);
x=0;
while(1) {
printf("%d %d %d\n",pos[0],pos[1],pos[2]);
fflush(stdout);
if(x==pos[0]||x==pos[1]||x==pos[2]) return 0;
scanf("%d",&x);
if(x==pos[0]||x==pos[1]||x==pos[2]) return 0;
get(x,pos[0],pos[1],pos[2]);
}
return 0;
}