Codeforces Round #150 (Div. 2)

A...随意搞

B.题意:从1~n(n<=1e9)中统计最多由两种不同数字组成的数的个数.

 解法:枚举两个数字,然后考虑每一位的情况,用二进制的思想..最后统计结果

B
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<set>
 5 using namespace std;
 6 typedef long long ll;
 7 int dig(ll n){
 8     int ans=0;
 9     while(n>0){
10         n/=10;
11         ans++;
12     }
13     return ans;
14 }
15 set<ll>s;
16 int main(){
17     ll n;
18     while(cin>>n){
19         int sz=dig(n);
20         s.clear();
21         for(int i=0;i<=9;i++){
22             for(int j=0;j<=9;j++){
23                 for(int k=1;k<(1<<sz);k++){
24                         ll p=1;
25                         ll num=0;
26                         int kk=k;
27                         while(kk>0){
28                             if(kk&1)
29                                 num+=i*p;
30                             else num+=j*p;
31                             kk>>=1;
32                             p*=10;
33                         }
34                         if(num<=n&&num>0){
35                             s.insert(num);
36                         }
37                     }
38             }
39         }
40         cout<<s.size()<<endl;
41     }
42     return 0;
43 }

C.题意:给定最多10^5个数,对某段区间进行或运算,问最后能出现的结果有多少种.

 解法:考虑数的每个二进制位,对于或运算来说,如果这个区间中某一位出现了1,那么最后的结果这一位一定是1,所以每次输入一个数,如果它的某个二进制位是0,就去前面找到第一个二进制位是1的数,然后判断结果...

p.s.时间复杂度不会证明,总觉得可能T...

C
 1 #include<iostream>
 2 #include<cstring>
 3 #include<set>
 4 #include<algorithm>
 5 #define N 100010
 6 using namespace std;
 7 int a[N];
 8 set<int>s;
 9 int main(){
10     int n;
11     while(cin>>n){
12         s.clear();
13         for(int i=1;i<=n;i++){
14             cin>>a[i];
15             s.insert(a[i]);
16             for(int j=0;j<20;j++){
17                 if(a[i]&(1<<j)){
18                     int sum=a[i];
19                     for(int k=i-1;k>=0&&!(a[k]&(1<<j));k--){
20                         sum|=a[k];
21                         s.insert(sum);
22                     }
23                 }
24             }
25         }
26         cout<<s.size()<<endl;
27     }
28     return 0;
29 }

D.题意:从一个图中找到一棵树,其中有一对顶点,一个连接h个点,一个连接t个点...输出方案.

 解法:先找出来所有能做head的点,然后去找和它相连的能做tail的点....

p.s.最开始是枚举边乱搞...一直找不出来trick...换了个思路才过..thinking....

D
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<map>
 5 #include<vector>
 6 #include<set>
 7 #define N 100010
 8 using namespace std;
 9 bool used[N];
10 vector<int>V[N],vh;
11 map<int,bool>s[N];
12 int main(){
13     int n,m,h,t;
14     while(cin>>n>>m>>h>>t){
15         for(int i=1;i<=n;i++){
16             V[i].clear();
17             s[i].clear();
18             used[i]=0;
19         }
20         vh.clear();
21         for(int i=1;i<=m;i++){
22             int a,b;
23             scanf("%d%d",&a,&b);
24             V[a].push_back(b);
25             V[b].push_back(a);
26             s[a][b]=1;
27             s[b][a]=1;
28         }
29         for(int i=1;i<=n;i++){
30             if(V[i].size()-1>=h)
31                 vh.push_back(i);
32         }
33         bool flag=0;
34         for(int i=0;i<vh.size()&&!flag;i++){
35             int v=vh[i],u;
36             int sum=V[v].size()-1;
37             for(int j=0;j<V[v].size()&&!flag;j++){
38 
39                 u=V[v][j];
40                 if(V[u].size()-1<t)continue;
41                 int tot=sum;
42                 for(int k=0;k<V[u].size();k++){
43                     if(V[u][k]!=v&&!s[v][V[u][k]])
44                         ++tot;
45                 }
46                 if(tot>=h+t){
47                     puts("YES");
48                     printf("%d %d\n",v,u);
49                     int num=0;
50                     for(int k=0;k<V[v].size()&&num<h;k++){
51                         if(V[v][k]!=u&&!s[u][V[v][k]]){
52                             printf("%d ",V[v][k]);
53                             num++;
54                             used[V[v][k]]=1;
55                         }
56                     }
57                     for(int k=0;k<V[v].size()&&num<h;k++){
58                         if(V[v][k]!=u&&!used[V[v][k]]){
59                             printf("%d ",V[v][k]);
60                             num++;
61                             used[V[v][k]]=1;
62                         }
63                     }
64                     puts("");
65                     num=0;
66                     for(int k=0;k<V[u].size()&&num<t;k++){
67                         if(V[u][k]!=v&&!used[V[u][k]]){
68                             printf("%d ",V[u][k]);
69                             num++;
70                             used[V[u][k]]=1;
71                         }
72                     }
73                     puts("");
74                     flag=1;
75                     break;
76                 }
77             }
78         }
79         if(!flag)
80         puts("NO");
81     }
82     return 0;
83 }

 

 

posted @ 2012-11-19 23:14  silver__bullet  阅读(150)  评论(0编辑  收藏  举报