A. Dungeon
对于每次到7,它都会增加两点伤害,题目问什么时候同时死,你直接模拟它们死光需要多少轮,以及是不是在这些轮里有人提前死了,判断一下就好了.
#include <bits/stdc++.h> using namespace std; int main() { int T; scanf("%d",&T); while(T--) { int a,b,c; cin>>a>>b>>c; int num=(a+b+c)/9; if((a+b+c)%9==0&&(a>=num&&b>=num&&c>=num)) puts("YES"); else puts("NO"); } return 0; }
B.Find The Array
已知两种构造方式:一种是构造二进制的最高位的数,另外一种是1,ai/ai,1这样构造
A.对于前者的做法来说呢,就是说因为一个数-一个数的最高位的数<一个数的最高位的数.所以相减的总和*2会小于原本的总和.
B.第二种分奇偶,肯定是有一半>=sum/2,另外一半<=sum/2的.
#include <bits/stdc++.h> using namespace std; int main() { int n,_; for(cin>>_;_;_--) { cin>>n; for(int i=1;i<=n;i++) { int x; cin>>x; cout<<(1<<(int)log2(x))<<' '; }puts(""); } return 0; }
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+50; int t[N],x[N]; int main() { int T; scanf("%d",&T); //T=1; while(T--) { int n;cin>>n; ll sum=0; for(int i=1;i<=n;i++) { scanf("%d",&x[i]); sum+=x[i]; } ll res=0;int flag1=0,flag2=0; for(int i=1;i<=n;i++) { if(i&1) res+=abs(x[i]-1); } if(res*2<=sum) flag1=1; else flag2=1; if(flag1) { for(int i=1;i<=n;i++) { if(i&1) cout<<1<<' '; else cout<<x[i]<<' '; } } if(flag2) { for(int i=1;i<=n;i++) { if(i&1) cout<<x[i]<<' '; else cout<<1<<' '; } } puts(""); } return 0; }
C. Busy Robot
题意很糟糕,读了很久.
题意:给你个机器人,每次在时间下达一个指令让它从当前位置走到,如果下达指令的时候正在执行的指令没有执行完(也就是没走到该走的位置),下达的指令就会被忽略.定义一个指令是合法的,当且仅当在这个指令和下个指令的时间段内(闭区间),机器人走到了这个指令要求的位置.问你有多少个指令合法?
思路:模拟就好.
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll ti[N],x[N]; int main() { int T; scanf("%d",&T); while(T--) { int lsq = 0; int n; scanf("%d",&n); ll d = 0,ans = 0; ll pos = 0,lst = 0,lstposx; bool ok = 1; for(int i = 1;i <= n;i++) scanf("%lld%lld",&ti[i],&x[i]); for(int i = 1;i <= n;i++) { ll lstpos = 0; if(ok) { ok = 0; if(pos <x[i])d = 1; else if(pos >x[i])d = -1; else { ok = 1; ans++; } lst = ti[i],lstposx =x[i]; } else { lstpos = pos; pos += d*(ti[i] - lst); if(d == 1) { if(pos >= lstposx) { pos = lstposx; ok = 1; } } else if(d == -1) { if(pos <= lstposx){ pos = lstposx; ok = 1; } } if(min(lstpos,pos)<=lsq&&lsq <= max(pos,lstpos)) { ans++; } lst = ti[i]; if(ok) { lstposx=x[i]; if(pos <x[i])d = 1; else if(pos >x[i])d = -1; ok = 0; } } if(i==n) { if((pos<=x[i]&&x[i]<=lstposx&&d==1)||(pos>=x[i]&&x[i]>=lstposx&&d==-1)) ans++; } lsq=x[i]; } printf("%lld\n",ans); } return 0; }
D:Pairs
题意简单,不说明了.想y了...
解法就是:田忌赛马,直接贪心就好了,两者都取最优解.
然后就是答案.
代码如下:
#include <bits/stdc++.h> using namespace std; const int N=2e5+50; int a[N<<1],b[N<<1]; bool vis[N<<1]; int main() { int _; for(cin>>_;_;_--) { int n,id=0;cin>>n; for(int i=1;i<=(n<<1);i++) vis[i]=false; for(int i=1;i<=n;i++) cin>>a[i],vis[a[i]]=true; for(int i=1;i<=2*n;i++) { if(!vis[i]) b[++id]=i; }sort(a+1,a+1+n); int max_x=0,min_x=0; //贪心怼就完事.类似田忌赛马? int j,i;i=n; for(j=n;j>=1;j--)//求min_x { if(a[i]<b[j]&&i) min_x++,i--; else { while(i&&a[i]>b[j]) i--; if(i) min_x++,i--; } }min_x=n-min_x; j=n; for(i=n;i>=1;i--)//求max_x { if(a[i]>b[j]&&j) max_x++,j--; else { while(j&&a[i]<b[j]) j--; if(j) max_x++,j--; } } cout<<abs(max_x-min_x)+1<<endl; } return 0; }
E.Plan of Lectures
首先可知,给定的一定是颗树,然后我们可以把要连在一起的放在同一个并查集里面,我们先预先遍历一遍,假如它们所在同一颗子树,那么可以提前处理出来,因为一定是符合拓扑序的,然后就是遍历这颗树,假如是单个的,直接加入答案,在并查集里面的呢,除非全部都遍历了,类似bfs吧?然后这样就好了.
#include <bits/stdc++.h> using namespace std; const int N=3e5+500; vector<int>v[N]; int fa[N],sz[N],nex[N],n,m; bool vis[N]; int dsu(int u) { if(u==fa[u]) return u; else return fa[u]=dsu(fa[u]); } //提前处理下树上相邻的情况,以及成环情况. bool ck() { for(int i=1;i<=n;i++) { if(!vis[dsu(i)]) { int u=dsu(i); while(nex[u]) { if(vis[u]) return false;//成环了. vis[u]=true;int num=v[u].size(); for(int i=0;i<num;i++) { int son=v[u][i]; if(dsu(son)!=dsu(u)) continue; if(vis[son]) return false; else sz[dsu(u)]--;//处理下在树上某个节点下方的情况. } u=nex[u]; } } }return true; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { fa[i]=i,sz[i]=1; int x;scanf("%d",&x); v[x].push_back(i); }//建树 for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); sz[dsu(x)]+=sz[dsu(y)]; fa[dsu(y)]=dsu(x); nex[x]=y; } deque<int>q; vector<int>ans; if(!ck()) { puts("0"); } else { for(int i=0;i<=n;i++) vis[i]=false; //遍历树寻求答案. q.push_back(0); while(q.size()) { int u=q.front();q.pop_front(); if(u) ans.push_back(u); if(nex[u]) q.push_front(nex[u]); int num=v[u].size(); for(int i=0;i<num;i++) { int son=v[u][i]; if(!vis[dsu(son)]) sz[dsu(son)]--; if(!vis[dsu(son)]&&!sz[dsu(son)]) q.push_back(dsu(son)),vis[dsu(son)]=true; } } int num=ans.size(); if(num==n) { for(int i=0;i<n;i++) printf("%d ",ans[i]);puts(""); } else puts("0"); } return 0; }