• 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

     

  • 相关阅读:
    在iphone上安装多个微信 【微信营销必备】
    微信 5.3 for iPhone已放出 微信iphone版更新下载
    支付宝也要上"服务号"?斗战微信继续升级
    微信事业群WXG成立 致力于打造微信大平台
    Matlab绘图系列之高级绘图
    朱亚东 临睡前发点鸡汤^^
    邢波老师致广大学员的一封信(2010-10-26)
    那些逐渐消失的技艺
    Nine Great Books about Information Visualization
    linux在shell中获取时间
  • 原文地址:https://www.cnblogs.com/q1204675546/p/11747502.html
Copyright © 2020-2023  润新知