10-20
Posted 杨树辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10-20相关的知识,希望对你有一定的参考价值。
比较水的题目吧
T1:给一个序列,序列中有四种操作,问有多少个非空子序列令一个机器人经过变换后再回到原位
数据量很小,n^2拿80,另外20只有左右两种命令,求一个类似于前缀和的东西,如果sumi==sumj证明有一种
#include<bits/stdc++.h> using namespace std; struct hehe{ int x,y; }; int n,cnt[800100]; char s[400100]; void work1(){ hehe a; int ans=0; for(int i=1;i<=n;++i){ a.x=0; a.y=0; for(int j=i;j<=n;++j){ if(s[j-1]==‘U‘) a.y++; else if(s[j-1]==‘D‘) a.y--; else if(s[j-1]==‘L‘) a.x--; else if(s[j-1]==‘R‘) a.x++; if(!a.x && !a.y) ans++; } } cout<<ans<<endl; } void work2(){ int x=0,ans=0; for(int i=1;i<=n;++i){ int xx=x; if(xx<0) xx=n-xx; ans+=cnt[xx]; cnt[xx]++; if(s[i-1]==‘L‘) x++; else if(s[i-1]==‘R‘) x--; } cout<<ans<<endl; } int main(){ freopen("command.in","r",stdin); freopen("command.out","w",stdout); cin>>n; scanf("%s",s); if(n<=4000) work1(); else work2(); fclose(stdin);fclose(stdout); return 0; }
T2:将n种颜色涂到n种卡片上,每种卡片有两张,将两张卡片一个正面朝上,一个反面朝上,打乱后将一个正面朝上的和一个反面朝上的放到一张桌子上(总共n张桌子),一个人会用1s的时间打开一个桌子上的反过来的卡片,并且走到另一个正面是这个颜色的桌子,对于Q次询问,求每次ki秒后这个人在哪站着。
对于30%的数据来说模拟即可,对于100%的数据来说,考虑到一定会出现循环的情况,做一个类似于连通分量的东西,求出每一个块的循环节y,那么问题就是每次询问的ki%y后的数怎么处理了。我的做法是开了一个结构体,存了每个桌子属于第几个块,在这个块中他是第几个,这样排序后就能O(1)的时间解决ki%y后的问题了
#include<bits/stdc++.h> using namespace std; struct hehe{ int x,y,dfn; }a[100100]; struct hh{ int op,id,s,dfn; }a1[100100]; struct haha{ int id,y; }e[100100]; int n,m,cnt=0,op[100100],kuai[100100],num=0,start[100100]; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘) f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch-‘0‘); ch=getchar();} return x*f; } inline void put(int x){ char ch[30]; int t=0; if(x<0){ putchar(‘-‘); x=-x; } else if(x==0) putchar(‘0‘); while(x){ ch[++t]=x%10+‘0‘; x/=10; } while(t) putchar(ch[t--]); putchar(‘\n‘); } void work1(){ int x,y; int cnt=0; for(int i=1;i<=m;++i){ x=read(); y=read(); for(cnt=1;cnt<=y;++cnt){ x=e[a[x].y].id; } put(x); } } int dfs(int x){ num++; op[x]=cnt; a[x].dfn=num; a1[x].dfn=num; a1[x].op=cnt; int Next=e[a[x].y].id; if(!op[Next]) dfs(Next); } bool mycmp(hh x,hh y){ return (x.op<y.op ||x.op==y.op && x.dfn<y.dfn); } void work2(){ for(int i=1;i<=n;++i){ if(!op[i]){ num=0; cnt++; int x=i; while(!op[x]){ op[x]=cnt; num++; a[x].dfn=num; a1[x].dfn=num; a1[x].op=cnt; x=e[a[x].y].id; } kuai[cnt]=num; } } sort(a1+1,a1+n+1,mycmp); for(int i=1;i<=n;++i){ if(a1[i].op==a1[i-1].op) a1[i].s=a1[i].s; else{ a1[i].s=i; start[a1[i].op]=i; } } int x,y; for(int i=1;i<=m;++i){ x=read(); y=read(); y+=a[x].dfn-1; int z=op[x]; y%=kuai[z]; int s=start[op[x]]+y; put(a1[s].id); } } int main(){ freopen("position.in","r",stdin); freopen("position.out","w",stdout); n=read(); m=read(); int x,y; for(int i=1;i<=n;++i){ x=read(); y=read(); e[x].y=y; e[x].id=i; a[i].x=x; a[i].y=y; a1[i].id=i; } if(n<=20) work1(); else work2(); fclose(stdin);fclose(stdout); return 0; }
T3:给一个图,边权为1,现要求从s1到t1不超过l1,从s2到t2不超过l2,求最多能删除多少边
求出每两个点之间的距离,然后枚举s1->t1,s2->t2的重叠的边,在剩下的图中尽量选用这些重叠的边,这样就能保证图中删掉的边是最多的
#include <iostream> #include <vector> #include <cstring> #include <queue> using namespace std; const int MAXN=3010; struct hehe{ int y,next; }e[10000]; int n, m,s1, t1, l1,s2, t2, l2,dis[MAXN][MAXN],lin[MAXN],len=0; bool vis[MAXN]; inline void insert(int x,int y){ e[++len].next=lin[x]; lin[x]=len; e[len].y=y; } inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘) f=-1; ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch-‘0‘); ch=getchar();} return x*f; } void bfs(){ for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); queue<int>q; q.push(i); vis[i]=1; while(!q.empty()){ int x=q.front(); q.pop(); for(int j=lin[x];j;j=e[j].next){ int y=e[j].y; if(!vis[y]){ vis[y]=1; dis[i][y]=dis[i][x]+1; q.push(y); } } } } } bool check(int s1, int t1, int s2, int t2, int i, int j){ return dis[s1][i]+dis[i][j]+dis[j][t1]<=l1 && dis[s2][i]+dis[i][j]+dis[j][t2]<=l2; } int main(){ freopen("destroy.in","r",stdin); freopen("destroy.out","w",stdout); n=read(); m=read(); int x,y; for (int i = 1; i <= m; i++){ x=read(); y=read(); insert(x,y); insert(y,x); } s1=read(); t1=read(); l1=read(); s2=read(); t2=read(); l2=read(); bfs(); int ans=dis[s1][t1]+dis[s2][t2]; if(dis[s1][t1]>l1 || dis[s2][t2]>l2){ cout<<"-1"<<endl; } else{ for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ if(check(s1,t1,s2,t2,i,j)){ ans = min(ans,dis[s1][i]+dis[i][j]+dis[j][t1]+dis[s2][i]+dis[j][t2]); } if(check(t1,s1,t2,s2,i,j)){ ans = min(ans,dis[t1][i]+dis[i][j]+dis[j][s1]+dis[t2][i]+dis[j][s2]); } if(check(s1,t1,t2,s2,i,j)){ ans = min(ans,dis[s1][i]+dis[i][j]+dis[j][t1]+dis[t2][i]+dis[j][s2]); } if(check(t1,s1,s2,t2,i,j)){ ans = min(ans,dis[t1][i]+dis[i][j]+dis[j][s1]+dis[s2][i]+dis[j][t2]); } } } cout<<m-ans<<endl; } return 0; }
T4emmmm
题目看不懂,题解看不懂,标程看不懂........
以上是关于10-20的主要内容,如果未能解决你的问题,请参考以下文章