加油 ( •̀ ω •́ )y!

Educational Codeforces Round 65 (Rated for Div. 2)

题目大意:给定你t个长度为N的字符串,问你能否通过删除字符串得到长度为11位且首位位8的电话号码。

思路:若N<11直接输出NO,N>=11 则枚举前 0  - (N-11)位,若其中有8出现则输出YES,否则是NO。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<vector>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 using namespace std;
11 typedef long long LL;
12 const int maxn = 1e5+10;
13 LL n,t;
14 string str;
15 int main()
16 {
17     cin>>t;
18     while(t--){
19         cin>>n;
20         cin>>str;
21         string ans = "NO";
22         for(int i=0;i<n-10;i++){
23             if(str[i]=='8'){
24                 ans = "YES";
25                 break;
26             }
27         }
28         cout<<ans<<endl;
29     }
30     return 0;
31 }
View Code

 

 

题目大意:(交互题)给定了六个数字,让你通过问四个问题,来判断当前这六个数字的排列顺序。

思路1:可以通过前两个问题,确定前两位;再通过询问两,相邻两位的乘积,确定之后三位数,最后一位就自动确定了。

思路2:枚举6位数字的全排列,判断是否满足询问的四个问题,四个问题必须涵盖五个数字或六个数字。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<vector>
 7 #include<cmath>
 8 #include<stack>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long LL;
13 const int maxn = 5e5+10;
14 LL n,m,tmp[10]={0,4,8,15,16,23,42};
15 int main()
16 {
17     int a[100];
18     for(int i=1;i<=4;i++){
19         if(i<=2)cout<<"? "<<i<<" "<<i<<endl;
20         else if(i==3)cout<<"? 3 4"<<endl;
21         else if(i==4)cout<<"? 4 5"<<endl;
22         fflush(stdout);
23         int num;
24         cin>>num;
25         if(i<=2)a[i] = sqrt(num);
26         else a[i] = num;
27     }
28     int la = a[3],lb = a[4];
29     // cout<<"la== "<<la<<" "<<lb<<endl;
30     int vis[10],len = 0;
31     for(int i=1;i<=6;i++){
32         if(tmp[i]!=a[1]&&tmp[i]!=a[2])
33             vis[len++]=tmp[i];
34     }
35     // for(int i=0;i<len;i++)cout<<vis[i]<<" ";
36     // cout<<endl;
37     int ra=-1,rb=-1,rc=-1,rd=-1;
38     for(int i=0;i<len-1;i++){
39         for(int j=i+1;j<len;j++){
40             if(vis[i]*vis[j]==a[3]){
41                 ra=vis[i];rb=vis[j];
42             }
43             if(vis[i]*vis[j]==a[4]){
44                 rc=vis[i];rd=vis[j];
45             }
46         }
47     }
48     // cout<<ra<<" "<<rb<<" "<<rc<<" "<<rd<<endl;
49     if(ra==rc)a[3]=rb,a[4]=ra,a[5]=rd;
50     else if(ra==rd)a[3]=rb,a[4]=ra,a[5]=rc;
51     else if(rb==rc)a[3]=ra,a[4]=rb,a[5]=rd;
52     else if(rb==rd)a[3]=ra,a[4]=rb,a[5]=rc;
53     for(int i=1;i<=6;i++){
54         int flag = 1;
55         for(int j=1;j<=5;j++){
56             if(a[j]==tmp[i]){
57                 flag = 0;
58                 break;
59             }
60         }
61         if(flag){
62             a[6]=tmp[i];
63             break;
64         }
65     }
66     cout<<"! "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<" "<<a[5]<<" "<<a[6]<<endl;
67     fflush(stdout);
68     return 0;
69 }
View Code

题目大意:有n个点,m个集合。集合可以合并的规则是,当本集合的数在另一个集合也出现过,则两集合可以合并。

思路:建图+DFS。

  对于每个集合,若集合中之后0或1个点,则跳过。否则:我们可以看成起点为 k[1] 到 k[i]有一条双向可达边,这样到最后就构成了一个联通图。

  最后DFS一遍,把每个集合中的顶点染色,在统计每种色彩的个数即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<vector>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 using namespace std;
11 typedef long long LL;
12 const int maxn = 5e5+10;
13 LL n,m;
14 vector<int>e[maxn];
15 map<int,int>mp;
16 int vis[maxn];
17 void dfs(int x,int dep){
18     if(x>n||x<1)return;
19     for(int i=0;i<e[x].size();i++){
20         if(!vis[e[x][i]]){
21             vis[e[x][i]]=dep;
22             dfs(e[x][i],dep);
23         }
24     }
25     return;
26 }
27 int main()
28 {
29     while(cin>>n>>m){
30         mp.clear();
31         for(int i=1;i<=n;i++)e[i].clear(),vis[i]=0;
32         while(m--){
33             int k,pre=-1;
34             cin>>k;
35             for(int x,i=1;i<=k;i++){
36                 cin>>x;
37                 if(i>1){
38                     e[pre].push_back(x);
39                     e[x].push_back(pre);
40                 }
41                 if(i==1)pre=x;
42             }
43         }
44         int cnt = 1;
45         for(int i=1;i<=n;i++){
46             if(!vis[i]){
47                 vis[i]=cnt;
48                 dfs(i,cnt++);
49             }
50         }
51         for(int i=1;i<=n;i++)
52             mp[vis[i]]++;
53         for(int i=1;i<n;i++)
54             cout<<mp[vis[i]]<<" ";
55         cout<<mp[vis[n]]<<endl;
56     }
57     return 0;
58 }
View Code

题目大意:给定一个RBS串(括号匹配的),问你怎么把它分解成两个RBS串,使得他们的最大嵌套深度最小。

思路:对于给定的RBS串,我们先遍历一遍求出最大的嵌套深度Max。那么Max/2 一定是满足题意的最小的的最大嵌套深度。

  在遍历一遍RBS串,若为'(' 且个数<Max/2 着将该位置标记为0,若为'('且个数>=Max/2 则标记为1;对于')’只要将其标记为与他对应的'('的数字即可。(这里0,1互换也可以)

  

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<vector>
 7 #include<cmath>
 8 #include<stack>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long LL;
13 const int maxn = 5e5+10;
14 LL n,m;
15 string str;
16 stack<int>S;
17 int main()
18 {
19     while(cin>>n){
20         while(S.size())S.pop();
21         cin>>str;
22         int ans = 0;
23         for(int i=0;i<n;i++){
24             if(str[i]=='(')S.push(i);
25             else S.pop();
26             ans = max(ans,int(S.size()));
27         }
28         while(S.size())S.pop();
29         ans /= 2;
30         string rs;
31         for(int i=0;i<n;i++){
32             if(str[i]=='('){
33                 if(S.size()<ans)S.push(0),rs.push_back('0');
34                 else S.push(1),rs.push_back('1');
35             }else{
36                 rs.push_back(char(S.top()+'0'));
37                 S.pop();
38             }
39         }
40         cout<<rs<<endl;
41     }
42     return 0;
43 }
View Code

 

posted @ 2019-05-17 10:49  皮皮虎  阅读(219)  评论(0编辑  收藏  举报