【Codeforces #167 Div1 & Div2】Solutions
【A. Dima and Friends】
http://www.codeforces.com/contest/272/problem/A
题目大意:n+1个人出手指头,加起来再做类似约瑟夫的出圈,问有多少种方法让自己不出圈。
1 #include <iostream> 2 using namespace std; 3 4 int n,a,sum,cnt; 5 6 int main(){ 7 cin>>n; 8 for(int i=0;i<n;i++){ 9 cin>>a; 10 sum+=a; 11 } 12 for(int i=1;i<=5;i++) 13 if((sum+i)%(n+1)!=1) cnt++; 14 cout<<cnt<<endl; 15 return 0; 16 }
【B.Dima and Sequence】
http://www.codeforces.com/contest/272/problem/B
题目大意:定义一个函数f(x),问给定数列an中有多少对函数值相同的数。
由函数的定义可以看出max{f(x)}并不非常大,由此可以记录下每一个数的函数值进行统计。
1 #include <iostream> 2 using namespace std; 3 4 int n,a,val[10000010]; 5 long long cnt; 6 7 int f(int x){ 8 if(!x) return x; 9 return (x&1)?(f((x-1)>>1)+1):f(x>>1); 10 } 11 12 int main(){ 13 cin>>n; 14 for(int i=0;i<n;i++){ 15 cin>>a; 16 cnt+=val[f(a)]++; 17 } 18 cout<<cnt<<endl; 19 return 0; 20 }
【C.Dima and Staircase】(A in Div1)
http://www.codeforces.com/contest/272/problem/C
题目大意:有一个楼梯,在楼梯第一层往下扔长为w,高为h的木块,规则类似俄罗斯方块,回答每个木块底边的高度。
楼梯高度是递增的,当一个木块落下时将影响1~w的所有高度,使他们的值相同。可以使用一个指针表示落下的木块形成的最高平台影响的区域1~p,并记录1~p的最高高度,每次只需要修改指针即可。
1 #include <iostream> 2 using namespace std; 3 4 int a[100010],n,m,w,h,cur; 5 long long maxh; 6 7 int main(){ 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 cin>>a[i]; 11 cin>>m; 12 for(int i=1;i<=m;i++){ 13 cin>>w>>h; 14 if(cur<w){ 15 if(a[w]>=maxh){ 16 cout<<a[w]<<endl; 17 maxh=a[w]+h; 18 cur=w; 19 }else{ 20 cout<<maxh<<endl; 21 maxh+=h; 22 cur=w; 23 } 24 }else{ 25 cout<<maxh<<endl; 26 maxh+=h; 27 cur=w; 28 } 29 } 30 return 0; 31 }
【D.Dima and Two Sequences】(B in Div1)
http://www.codeforces.com/contest/272/problem/D
题目大意:有2*n个点,问有多少种方法使得他们按x坐标不减排序。
对于x坐标相同的点,一共有种排列方法,但是关键问题是其中有重复的点,重复的点互相交换位置不引起方案的变化,设重复点有k个,则方案数为。
因为除数只含有因子2,且被除数含有的因子2一定比分母含有的多,所以在算阶乘的时候逐个除去因子2。
最后各个不同x坐标的方案数的乘积为答案。
1 #include <iostream> 2 #include <utility> 3 #include <algorithm> 4 using namespace std; 5 typedef pair<int,int> PII; 6 7 int x,n,BASE,t,same; 8 PII p[200010]; 9 long long ans=1; 10 11 int main(){ 12 cin>>n; 13 for(int i=0;i<2*n;i++){ 14 cin>>x; 15 p[i]=PII(x,i%n); 16 } 17 cin>>BASE; 18 sort(p,p+2*n); 19 int i=0,j=0; 20 while(i<2*n){ 21 while(j<=2*n && p[j+1].first==p[j].first) 22 if(p[++j].second==p[j-1].second) same++; 23 for(int k=2;k<=j-i+1;k++){ 24 t=k; 25 while(!(t&1) && same) t/=2,same--; 26 ans=(ans*t)%BASE; 27 } 28 i=++j; 29 } 30 cout<<ans<<endl; 31 return 0; 32 }
【E.Dima and Horses】(C in Div1)
http://www.codeforces.com/contest/272/problem/E
题目大意:有一群马,马之间有仇恨关系,将马分成两组,使得任意一匹马在分组中最多只有一个仇恨关系。
因为m最大是n(n-1)/2,所以应该没有无解的情况。。仇恨关系不超过三个,所以dfs一下就可以了。
1 #include <iostream> 2 using namespace std; 3 4 int n,m,x,y,f[300010],a[300010][4]; 5 6 void dfs(int x){ 7 int cnt=0; 8 for(int i=1;i<=a[x][0];i++) 9 cnt+=f[x]==f[a[x][i]]; 10 if(cnt>1){ 11 f[x]^=1; 12 for(int i=1;i<=a[x][0];i++) 13 if(f[x]==f[a[x][i]]) dfs(a[x][i]); 14 } 15 } 16 17 int main(){ 18 cin>>n>>m; 19 while(m--){ 20 cin>>x>>y; 21 a[x][++a[x][0]]=y; 22 a[y][++a[y][0]]=x; 23 } 24 for(int i=1;i<=n;i++) 25 dfs(i); 26 for(int i=1;i<=n;i++) 27 cout<<f[i]; 28 }
【D.Dima and Figure】(Div 1)
http://www.codeforces.com/contest/273/problem/D