Codeforces Round #592 (Div. 2) A,B,C,D,E

题目:A. Pens and Pencils

 

题意思路:略

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int q,a,b,c,d,k;
 6     cin>>q;
 7     while(q--){
 8         cin>>a>>b>>c>>d>>k;
 9         bool flag=false;
10         int ans1=0,ans2=0;
11         for (int i=1;i<=k;i++){
12             if (i*c>=a&&(k-i)*d>=b){
13                 ans1=i;
14                 ans2=(k-i);
15                 flag=true;
16                 break;
17             }
18         }
19         if (flag)
20             cout<<ans1<<" "<<ans2<<endl;
21         else
22             cout<<"-1"<<endl;
23     }
24     return 0;
25 }
AC

 

 

题目:B. Rooms and Staircases

 

题意:

    旅馆存在两楼,每层楼的房间数都为n,0代表该房间门口无楼梯,1代表有楼梯

         问小明从任意房间出发,一个房间只能路过一次,求可以路过房间的数量    的最大值

 

思路:

1.从第一层最左端点出发,找离的最远的楼梯上去,再返会到第二层最左端   路过的房间数记录下来

2.从第一层最右端点出发,找离的最远的楼梯上去,再返回到第二层最右端   路过的房间数记录下来

  上述两者取最大值输出即可。

 

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 char str[1010];
 7 bool vis[5][1010];
 8 int main()
 9 {
10     int q,n;
11     cin>>q;
12     while (q--){
13         cin>>n>>str+1;
14         int tmp=-1,ans=n;
15         for (int i=1;i<=n;i++){
16             if (str[i]=='1'){
17                 tmp=i;
18                 break;
19             }
20         }
21         if (tmp!=-1)
22             ans=max(ans,(n-tmp+1)*2);
23         for (int i=n;i>=1;i--){
24             if (str[i]=='1'){
25                 tmp=i;
26                 break;
27             }
28         }
29         if (tmp!=-1)
30             ans=max(ans,(tmp*2));
31         cout<<ans<<endl;
32     }
33     return 0;
34 }
AC

 

题目:C. The Football Season

题意:

  已知整数   n,p,w,d

  其中    n是游戏总局数,p是总得分,赢了得w分,平局得d分

  求    x,y,z值,     分别为赢的局数,平的局数,输的局数

    显然满足以下方程

      x*w+y*d=p

      x+y+z=n

   若存在xyz,则输出x,y,z值,不存在则输出-1

 

思路:

  先看一下数据范围  (1n1e12,0p1e17,1d<w1e5),如果用线性的算法的话,只能围绕d和w。

  x*w+y*d=p      变形------>    x= (p-d*y)%w         ,然后根据取余规律,x的范围在【0,w-1】,即【0,1e5-1】;然后直接暴力了。

 

 1 #include<iostream>
 2 typedef long long ll;
 3 using namespace std;
 4 int main()
 5 {
 6     ll n,p,w,d,x,y,z;
 7     cin>>n>>p>>w>>d;
 8     bool flag=false;
 9     for (int i=0;i<w;i++){
10         if ((p-(d*i))%w==0&&(p-(d*i))/w+i<=n&&p>=d*i){
11             x=(p-(d*i))/w;
12             y=i;
13             z=n-x-y;
14             flag=true;break;
15         }
16     }
17     if (flag){
18         cout<<x<<" "<<y<<" "<<z<<endl;
19     }
20     else
21         cout<<-1<<endl;
22     return 0;
23 }
AC

 

D. Paint the Tree

 

题意:

  有三种颜色,要给n个点进行涂色,不同结点涂不同颜色,具有不同花费,问在任意连续的直接相连的三个结点之间不存在同种颜色的情况下,求最小花费

思路:

  从入度为1的点出发(如果存在入度大于2的点,就直接输出-1),然后分六种情况,

  分别是12,13,21,23,31,32  (23的意思是第一个结点涂颜色2,二块涂颜色3,后面如果不想连续三个结点之间重复颜色的点,必定是231循环涂色)

  六种情况取涂色花费最小值即可。

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long int ll;
 4 ll a[4][100004];
 5 vector <ll> v[100004];
 6 ll t[6][3]={{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}};
 7 ll ans[6];
 8 ll lans[6][100004];
 9 void dfs (ll i,ll j,ll k,ll count){
10     ll temp=count%3;
11     ans[k]+=a[t[k][temp]][i];
12     lans[k][i]=t[k][temp];
13     for (ll m=0;m<v[i].size();m++)
14     {
15         if (v[i][m]!=j)
16         {
17             dfs(v[i][m],i,k,count+1);
18         }
19     }
20 }
21 int main(){
22     ll n;
23     cin>>n;
24     memset(ans,0,sizeof(ans));
25     for (ll i=1;i<=3;i++){
26         for (ll j=1;j<=n;j++){
27             cin>>a[i][j];
28         }
29     }
30     for (ll i=0;i<n-1;i++)
31     {
32         ll c,d;
33         cin>>c>>d;
34         v[c].push_back(d);
35         v[d].push_back(c);
36     }
37     ll leaf;
38     for (ll i=1;i<=n;i++)
39     {
40         if (v[i].size()>2)
41         {
42             cout<<-1;
43             exit(0);
44         }
45         if (v[i].size()==1)
46             leaf=i;
47     }
48     ll ans_min=1e18;
49     ll ind;
50     for (ll i=0;i<6;i++)
51     {
52         dfs(leaf,-1,i,0);
53         // cout<<ans[i]<<" ";
54         if (ans[i]<ans_min)
55         {
56             ans_min=ans[i];
57             ind=i;
58         }
59     }
60     cout<<ans[ind]<<endl;
61     for (ll i=1;i<=n;i++)
62         cout<<lans[ind][i]<<" ";
63 }
AC

 

 

E. Minimizing Difference

 

题意:

   给你n个数,最多k次操作(操作次数可以小于k),每次操作只能让一个数+1或者-1,问  该数组的最大值 - 该数组的最小值       最小为多少

 

思路:

   先排序一下,然后只需要对最小值进行+1,最大值进行-1。  

  问题只需要解决什么时候进行+1,什么时候进行-1。

  只需要看最小值的数量和最大值的数量谁更少,若最小值的数量少,则所以最小值+1,反之最大值-1。(其实就是看谁的操作次数少能让max-min的值可以改变)

 

 1 #include<iostream>
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5  
 6 const int MAXN=1e5+10;
 7 struct Node{
 8     ll a,cnt;
 9 }mp[MAXN],bt[MAXN];
10 bool cmp(const Node&a,const Node&b){
11     if (a.a!=b.a)
12         return a.a<b.a;
13 }
14 ll n,k;
15 int main(){
16     scanf("%lld%lld",&n,&k);
17     for (int i=1;i<=n;i++){
18         scanf("%lld",&mp[i].a);
19         mp[i].cnt=0;
20     }    
21     sort(mp+1,mp+n+1,cmp);
22     ll L=1,R=1,tmp=1;
23     for (int i=2;i<=n;i++){
24         if (mp[i].a==mp[i-1].a){
25             tmp++;
26         }
27         else if (mp[i].a!=mp[i-1].a){            
28             bt[R].cnt=tmp;
29             bt[R].a=mp[i-1].a;
30             R++;
31             tmp=1;
32         }
33         if (i==n){
34             bt[R].cnt=tmp;
35             bt[R].a=mp[i].a;
36         }
37     }
38     ll ans=bt[R].a-bt[L].a;
39 //    cout<<ans<<endl;
40     while(k>0&&L<R){
41         if (bt[L].cnt>bt[R].cnt){
42             if (k<bt[R].cnt)
43                 break;
44             if (k>=bt[R].cnt*(bt[R].a-bt[R-1].a)){
45                 k-=bt[R].cnt*(bt[R].a-bt[R-1].a);
46                 R--;
47                 bt[R].cnt+=bt[R+1].cnt;
48                 ans=min(ans,bt[R].a-bt[L].a);                
49             }
50             else{
51                 ll tmp=k/bt[R].cnt;
52                 k-=bt[R].cnt*tmp;
53                 bt[R].a-=tmp;
54                 ans=min(ans,bt[R].a-bt[L].a);
55             }
56         }
57         else{
58             if (k<bt[L].cnt)
59                 break;
60             if (k>=bt[L].cnt*(bt[L+1].a-bt[L].a)){
61                 k-=bt[L].cnt*(bt[L+1].a-bt[L].a);
62                 L++;
63                 bt[L].cnt+=bt[L-1].cnt;
64                 ans=min(ans,bt[R].a-bt[L].a);             
65             }
66             else{
67                 ll tmp=k/bt[L].cnt;
68                 k-=tmp*bt[L].cnt;
69                 bt[L].a+=tmp;
70                 ans=min(ans,bt[R].a-bt[L].a);
71             }
72         }        
73     }
74     cout<<ans<<endl;
75     return 0;
76 } 
AC

 

 

 

posted @ 2019-10-27 14:37  生活待我如初恋  阅读(164)  评论(0编辑  收藏  举报