3.16

https://vjudge.net/contest/154390#problem

A题

题意:给你27个字符分别有I L E三种组成,问你是否能组组成3*3*3的一整块?

思路:可以发现当字符为 I 和 L时它的下一个块的位置固定,当字符是 L 时他有四个方向,所以利用深搜去搜索出是否可能组成。

 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 int flag[3][3][3];
 5 char s[30];
 6 int ans;
 7 int b[6][3]= {{1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1}};
 8 void dfs(int i,int j,int k,int p,int tmp)
 9 {
10     int x,y,z;
11     if(tmp==26)
12     {
13         if(!flag[i][j][k])
14         {
15             ans=1;
16             return ;
17         }
18         else
19         {
20             return ;
21         }
22     }
23     if(s[tmp]=='I')
24     {
25         x=i+b[p][0],y=j+b[p][1],z=k+b[p][2];
26         if(x>=0&&x<=2&&y>=0&&y<=2&&z>=0&&z<=2&&!flag[i][j][k])
27         {
28             flag[i][j][k]=1;
29             dfs(x,y,z,p,tmp+1);
30             flag[i][j][k]=0;
31         }
32     }
33     else if(s[tmp]=='L')
34     {
35         for(int t=0; t<6; t++)
36         {
37             if(t%3==p%3)
38                 continue;
39             x=i+b[t][0],y=j+b[t][1],z=k+b[t][2];
40             if(x>=0&&x<=2&&y>=0&&y<=2&&z>=0&&z<=2&&!flag[i][j][k])
41             {
42                 flag[i][j][k]=1;
43                 dfs(x,y,z,t,tmp+1);
44                 flag[i][j][k]=0;
45             }
46             if(ans)
47                 break;
48         }
49     }
50     return ;
51 }
52 int main()
53 {
54     while(~scanf("%s",s))
55     {
56         ans=0;
57         for(int i=0; i<3; i++)
58         {
59             for(int j=0; j<3; j++)
60             {
61                 for(int k=0; k<3; k++)
62                 {
63                     int x=i+b[0][0],y=j+b[0][1],z=k+b[0][2];
64                     memset(flag,0,sizeof(flag));
65                     if(x>=0&&x<=2&&y>=0&&y<=2&&z>=0&&z<=2&&!flag[i][j][k])
66                     {
67                         flag[i][j][k]=1;
68                         dfs(x,y,z,0,1);
69                         flag[i][j][k]=0;
70                     }
71                     if(ans)
72                         break;
73                 }
74                 if(ans)
75                     break;
76             }
77             if(ans)
78                 break;
79         }
80         if(ans)
81             printf("YES\n");
82         else
83             printf("NO\n");
84     }
85     return 0;
86 }
View Code

B题

题意:给出两个有相同数量的叶子节点的树,问你最少需要多少种颜色进行染色。

思路:通过画图能知道最少的颜色只有2和3两种可能,其中若对A树从一个非叶子节点开始到所有叶子节点所走距离是奇数和偶数的数量和B树相同的话最少颜色一定是2,如果A的奇数数量等于B树的偶数数量那么结果还是2,否则是3。

  1 #include <iostream>
  2 #include <queue>
  3 #include <vector>
  4 #include <bits/stdc++.h>
  5 using namespace std;
  6 const int maxn=100005;
  7 vector<int>mp[maxn];
  8 queue<int>que1,que2;
  9 int flag[maxn],ans1[maxn],ans2[maxn];
 10 void dfs(int x,int step)
 11 {
 12     int tmp=0;
 13     for(int i=0; i<mp[x].size(); i++)
 14     {
 15         if(!flag[mp[x][i]])
 16         {
 17             tmp=1;
 18             flag[mp[x][i]]=1;
 19             dfs(mp[x][i],step+1);
 20         }
 21     }
 22     if(tmp==0)
 23     {
 24         if(step%2==1)
 25             que1.push(x);
 26         else
 27             que2.push(x);
 28     }
 29     return ;
 30 }
 31 int main()
 32 {
 33     int u,v,n,m;
 34     while(~scanf("%d",&n))
 35     {
 36         for(int i=0; i<maxn; i++)
 37             mp[i].clear();
 38         for(int i=0; i<n-1; i++)
 39         {
 40             scanf("%d%d",&u,&v);
 41             mp[u].push_back(v);
 42             mp[v].push_back(u);
 43         }
 44         memset(flag,0,sizeof(flag));
 45         while(!que1.empty())
 46             que1.pop();
 47         while(!que2.empty())
 48             que2.pop();
 49         for(int i=1; i<=n; i++)
 50             if(mp[i].size()>1)
 51             {
 52                 flag[i]=1;
 53                 dfs(i,1);
 54                 break;
 55             }
 56         int k1=0,k2=0;
 57         while(!que1.empty())
 58         {
 59             ans1[k1++]=que1.front();
 60             que1.pop();
 61         }
 62         while(!que2.empty())
 63         {
 64             ans2[k2++]=que2.front();
 65             que2.pop();
 66         }
 67         scanf("%d",&m);
 68         for(int i=0; i<maxn; i++)
 69             mp[i].clear();
 70         for(int i=0; i<m-1; i++)
 71         {
 72             scanf("%d%d",&u,&v);
 73             mp[u].push_back(v);
 74             mp[v].push_back(u);
 75         }
 76         memset(flag,0,sizeof(flag));
 77         for(int i=1; i<=m; i++)
 78             if(mp[i].size()>1)
 79             {
 80                 flag[i]=1;
 81                 dfs(i,1);
 82                 break;
 83             }
 84         if(que1.size()==k1||que2.size()==k1)
 85         {
 86             printf("2\n");
 87             int t=0;
 88             if(k1==que1.size())
 89             {
 90                 while(!que1.empty())
 91                 {
 92                     printf("%d %d\n",ans1[t++],que1.front());
 93                     que1.pop();
 94                 }
 95                 t=0;
 96                 while(!que2.empty())
 97                 {
 98                     printf("%d %d\n",ans2[t++],que2.front());
 99                     que2.pop();
100                 }
101             }
102             else
103             {
104                 while(!que2.empty())
105                 {
106                     printf("%d %d\n",ans1[t++],que2.front());
107                     que2.pop();
108                 }
109                 t=0;
110                 while(!que1.empty())
111                 {
112                     printf("%d %d\n",ans2[t++],que1.front());
113                     que1.pop();
114                 }
115             }
116         }
117         else
118         {
119             printf("3\n");
120             for(int i=0; i<k2; i++)
121                 ans1[i+k1]=ans2[i];
122             int t=0;
123             while(!que1.empty())
124             {
125                 ans2[t++]=que1.front();
126                 que1.pop();
127             }
128             while(!que2.empty())
129             {
130                 ans2[t++]=que2.front();
131                 que2.pop();
132             }
133             for(int i=0; i<t; i++)
134                 printf("%d %d\n",ans1[i],ans2[i]);
135         }
136 
137     }
138     return 0;
139 }
View Code

C题

D题

题意:有n台坏电脑,A修好一台要a分钟,B要b分钟,问两人一起修好n台的最短时间。

思路:使用二分将n分成A要修的台数和剩下B要修的台数,求两者的最大值的最小值。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <bits/stdc++.h>
 7 using namespace std;
 8 int main()
 9 {
10     long long n,x,y;
11     while(~scanf("%I64d%I64d%I64d",&n,&x,&y))
12     {
13         long long l=0,r=n;
14         if(x>y)
15             swap(x,y);
16         long long ans=n*y,len=n*y;
17         long long mid;
18         while(l<=r)
19         {
20             mid=(l+r)/2;
21             if(mid*x<(n-mid)*y)
22             {
23                 l=mid+1;
24             }
25             else if ((n-mid)*y<mid*x)
26             {
27                 r=mid-1;
28             }
29             if(len>max((n-mid)*y,mid*x))
30             {
31                 len=max((n-mid)*y,mid*x);
32             }
33             if((n-mid)*y==x*mid)
34             {
35                 len=x*mid;
36                 break;
37             }
38         }
39         printf("%I64d\n",len);
40     }
41     return 0;
42 }
View Code

E题

题意:给你两个三角形的六个顶点,问组成的新图形有几个顶点?

思路:两个三角形有1 2 3个顶点重合,新图形有6 4 3个顶点

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int a,b,c,d,e,f;
10     while(cin>>a>>b>>c>>d>>e>>f)
11     {
12         int t=0;
13         if(a==d) t++;
14         if(a==e) t++;
15         if(a==f) t++;
16         if(b==d) t++;
17         if(b==e) t++;
18         if(b==f) t++;
19         if(c==d) t++;
20         if(c==e) t++;
21         if(c==f) t++;
22         if(t==0||t==1) cout<<6<<endl;
23         else if(t==2) cout<<4<<endl;
24         else cout<<3<<endl;
25     }
26     return 0;
27 }
View Code

F题

G题

题意:一群人做同一个题,给你做之前的分数和这道题的分值,问排名存在变化的可能性。

思路:没想明白呢

 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int maxn=100005;
 5 int a[maxn];
 6 double cnt[maxn],sum[maxn];
 7 int cmp(const int &a,const int &b)
 8 {
 9     return a>b;
10 }
11 int main()
12 {
13     int n,m;
14 //    int c[12]={12,15,17,19,20,22,23,26,29,35,40,51};
15 //    for(int i=0;i<12;i++)
16 //        b[i]=c[11-i];
17 //    int k=upper_bound(b,b+10,20,cmp)-b;
18 //    printf("%d\n",k);
19     while(~scanf("%d%d",&n,&m))
20     {
21         for(int i=0;i<n;i++)
22         {
23             scanf("%d",&a[i]);
24         }
25         for(int i=0;i<n;i++)
26         {
27             scanf("%lf",&cnt[i]);
28             if(i==0)
29                 sum[i+1]=cnt[i];
30             else
31             {
32                 sum[i+1]=sum[i]+cnt[i];
33             }
34         }
35         double ans=0.0;
36         for(int i=0;i<n;i++)
37         {
38             int l=upper_bound(a,a+i+1,a[i]+m,cmp)-a;
39             int r=lower_bound(a,a+i+1,a[i],cmp)-a;
40             //printf("%d %d\n",l,r);
41             ans+=(sum[r]-sum[l])*(1.0-cnt[i]);
42         }
43         printf("%.9lf\n",ans);
44 
45     }
46     return 0;
47 }
View Code

H题

题意:给你一系列数让你进行n-1次相邻的两个数合并,再把每次合并之后的数进行相加,求最小的总和。

思路:经过几次计算就会发现当总和最小时,n加了(n-1)次,(n-1)加了(n-2)次,依次类推,就能求出最后的和。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <bits/stdc++.h>
 4 using namespace std;
 5 typedef long long ll;
 6 ll a[100005];
 7 int main()
 8 {
 9     ll n;
10     while(cin>>n)
11     {
12         scanf("%I64d",&a[0]);
13         for(int i=1;i<n;i++)
14         {
15             scanf("%I64d",&a[i]);
16 
17         }
18         sort(a,a+n);
19         ll sum=0;
20         for(int i=0;i<n;i++)
21         sum+=a[i]*i;
22         printf("%I64d\n",sum);
23 
24 
25 
26     }
27     return 0;
28 }
View Code

I题

posted @ 2017-03-23 17:33  Wally的博客  阅读(129)  评论(0编辑  收藏  举报