Codeforces Round #190 (Div. 2)
2013-06-29 19:16
806 查看
A题:直接输出就好了,除了最后一个人不能跳外,其他的每个人first time dancing一次,总共可以跳 n+m-1次,代码如下:
B题:先把a,b,c排升序,然后用贪心的思路,设每种颜色取一次的方案数x,把x枚举3次就好了,即从a-3~a,代码如下:
C题:直接向量来解,只要存在在走的过程的一个点加k倍的走的起点终点向量等于实际的终点向量,就是yes,比赛的时候少考虑了一种情况,没能通过sys test,悲剧,后ac代码如下:
D题:贪心,分两种情况,第一种:要么用最大的减最小的,具体的个数可以用枚举;第二种:如果可以全部杀死,用最接近盾牌的力量去杀盾牌,后面就是用能杀的去杀,最后取两种情况的最优值,代码如下:
E题:用求树重心的方法重构这颗树,那么重构后的树的深度为logn,这样我们可以在每一层放一个字母,就可以符合题意了,又因为n<=100000,即logn<=26,所以总是有解的,代码如下:
#include<stdio.h> #include<string.h> int main() { int n,m,i; while(scanf("%d%d",&n,&m)!=EOF) { printf("%d\n",m+n-1); for(i=1;i<=m;i++){ printf("1 %d\n",i); } for(i=2;i<=n;i++){ printf("%d 1\n",i); } } return 0; }
B题:先把a,b,c排升序,然后用贪心的思路,设每种颜色取一次的方案数x,把x枚举3次就好了,即从a-3~a,代码如下:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int main() { int i,l,r,a,b,c,ans; while(scanf("%d%d%d",&a,&b,&c)!=EOF) { if(a>c) swap(a,c); if(a>b) swap(a,b); if(b>c) swap(b,c); ans=0; l=a-3>0?a-3:0; r=a; for(i=l;i<=r;i++){ if(i+(b-i)/3+(c-i)/3>ans) ans=i+(b-i)/3+(c-i)/3; } printf("%d\n",ans); } return 0; }
C题:直接向量来解,只要存在在走的过程的一个点加k倍的走的起点终点向量等于实际的终点向量,就是yes,比赛的时候少考虑了一种情况,没能通过sys test,悲剧,后ac代码如下:
#include<stdio.h> #include<string.h> struct point { int x,y; point(int a=0,int b=0):x(a),y(b){} }; point operator+(point a,point b){ return point(a.x+b.x,a.y+b.y); } point operator-(point a,point b){ return point(a.x-b.x,a.y-b.y); } int operator%(point a,point b){ if((a.x!=0&&b.x==0)||(a.y!=0&&b.y==0)) return 0; if(a.x==0&&b.x==0&&a.y==0&&b.y==0) return 1; if(b.x&&!b.y) return a.x%b.x==0&&(a.x/b.x)>=0; else if(!b.x&&b.y) return a.y%b.y==0&&(a.y/b.y)>=0; else return a.x%b.x==0&&a.y%b.y==0&&(a.x/b.x)==(a.y/b.y)&&(a.x/b.x)>=0&&(a.y/b.y)>=0; } char s[110]; point dest[110]; void precal(int n) { int i,x=0,y=0; dest[0]=point(0,0); for(i=0;i<n;i++) { switch(s[i]){ case 'U':y+=1;break; case 'D':y-=1;break; case 'L':x-=1;break; case 'R':x+=1;break; } dest[i+1]=point(x,y); } } int main() { int a,b,n,i; point d; while(scanf("%d%d",&a,&b)!=EOF) { scanf("%s",s);n=strlen(s); precal(n); d=point(a,b); for(i=0;i<=n;i++) if((d-dest[i])%dest ) break; puts(i<=n?"Yes":"No"); } return 0; }
D题:贪心,分两种情况,第一种:要么用最大的减最小的,具体的个数可以用枚举;第二种:如果可以全部杀死,用最接近盾牌的力量去杀盾牌,后面就是用能杀的去杀,最后取两种情况的最优值,代码如下:
#include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; int vis[110]; vector<int> Atk,Def,Ciel; int main() { char op[10]; int n,m,i,j,k,ans,tmp; while(scanf("%d%d",&n,&m)!=EOF) { Atk.clear(); Def.clear(); Ciel.clear(); for(i=1;i<=n;i++){ scanf("%s%d",op,&k); if(op[0]=='A') Atk.push_back(k); else Def.push_back(k); } for(i=1;i<=m;i++){ scanf("%d",&k);Ciel.push_back(k); } sort(Atk.begin(),Atk.end()); sort(Def.begin(),Def.end()); sort(Ciel.begin(),Ciel.end()); for(i=1,ans=0;i<=m;i++){ if(Atk.size()<i) break; for(j=tmp=0;j<i;j++) { if(Ciel[m-i+j]<Atk[j]) break; tmp+=Ciel[m-i+j]-Atk[j]; } if(j>=i&&tmp>ans) ans=tmp; } memset(vis,0,sizeof(vis)); for(i=k=0;i<Ciel.size();i++) { if(k<Def.size()&&Ciel[i]>Def[k]) k++,vis[i]=1; } if(k==Def.size()){ for(i=k=tmp=0;i<Ciel.size();i++) { if(vis[i])continue; tmp+=Ciel[i]; if(k<Atk.size()&&Ciel[i]>=Atk[k]){ tmp-=Atk[k]; k++; } } if(k==Atk.size()&&tmp>ans) ans=tmp; } printf("%d\n",ans); } return 0; }
E题:用求树重心的方法重构这颗树,那么重构后的树的深度为logn,这样我们可以在每一层放一个字母,就可以符合题意了,又因为n<=100000,即logn<=26,所以总是有解的,代码如下:
#include<stdio.h> #include<queue> #include<string.h> using namespace std; struct E { int to,next; }edge[200010]; int head[100010],ant,cnt[100010],vis[100010],T,Min; void add(int a,int b) { edge[ant].to=b; edge[ant].next=head[a]; head[a]=ant++; } int Max(int a,int b){ return a<b?b:a; } void dfs(int root,int pa) { int to,i; cnt[root]=1; for(i=head[root];i!=-1;i=edge[i].next) { to=edge[i].to; if(to==pa||vis[to]) continue; dfs(to,root); cnt[root]+=cnt[to]; } } void sovle(int root,int pa,int up) { int to,i,sum=up; for(i=head[root];i!=-1;i=edge[i].next) { to=edge[i].to; if(to==pa||vis[to]) continue; sovle(to,root,cnt[root]+up-cnt[to]); sum=Max(sum,cnt[to]); } if(sum<Min){ Min=sum;T=root;} } int main() { int n,i,a,b,to; while(scanf("%d",&n)!=EOF) { ant=0; memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b);add(b,a); } Min=n+n; dfs(1,-1);sovle(1,-1,0); queue <int> que; que.push(T);vis[T]=1; while(!que.empty()){ int u=que.front();que.pop(); for(i=head[u];i!=-1;i=edge[i].next) { to=edge[i].to; if(to==u||vis[to]) continue; Min=n+n; dfs(to,-1);sovle(to,-1,0); vis[T]=vis[u]+1; que.push(T); } } for(i=1;i<n;i++) printf("%c ",vis[i]-1+'A'); printf("%c\n",vis[i]-1+'A'); } return 0; }
相关文章推荐
- Codeforces Round #190 (Div. 2)---A. Ciel and Dancing
- Codeforces Round #190 (Div. 2)-C. Ciel and Robot
- Codeforces Round #190 (Div. 2)(完全)
- Codeforces Round #190 (Div. 2前三题)
- Codeforces Round #190 (Div. 2) B. Ciel and Flowers
- Codeforces Round #190 (Div. 2) A B C
- Codeforces Round #190 (Div. 2).D
- Codeforces Round #190 (Div. 2) 总结
- Codeforces Round #190 (Div. 2) 解题报告
- Codeforces Round #190 (Div. 2) 解题报告
- Codeforces Round #190 (Div. 2) E. Ciel the Commander 题目与题解翻译
- Codeforces Round #190 (Div. 2) 水果俩水题
- Codeforces Round #190 (Div. 2) E. Ciel the Commander 题目与题解翻译
- Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
- Codeforces Round #190 (Div. 2) 水果俩水题
- [置顶] Codeforces Round #190 (Div. 2)(完全)
- 想法题——Codeforces Round #190 (Div. 2)——B. Ciel and Flowers
- Codeforces Round #224 (Div. 2) D. Ksenia and Pawns
- Codeforces Round #277.5 (Div. 2) C Given Length and Sum of Digits...
- Codeforces Round 40 (Rated for Div. 2) B 字符串 不互用字符字串问题