【Codeforces #167 Div1 & Div2】Solutions

【A. Dima and Friends】

  http://www.codeforces.com/contest/272/problem/A

  题目大意:n+1个人出手指头,加起来再做类似约瑟夫的出圈,问有多少种方法让自己不出圈。

View Code
 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)}并不非常大,由此可以记录下每一个数的函数值进行统计。

View Code
 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的最高高度,每次只需要修改指针即可。

View Code
 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坐标的方案数的乘积为答案。

View Code
 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一下就可以了。

View Code
 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

  

  

posted @ 2013-02-14 20:37  Delostik  阅读(616)  评论(5编辑  收藏  举报