zoukankan      html  css  js  c++  java
  • 2018acm区域赛青岛

    zoj4060

    思维题目+找规律,比较难想!

    划分不同块,找不同块。

    根据不同块的数目又分为4种情况。(划分块就够难想了,这4种情况计算规律更是难找!)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 ll n;
     7 string s,t;
     8 
     9 int main()
    10 {
    11     ios::sync_with_stdio(0); cin.tie(0);
    12     
    13     int T;
    14     cin>>T;
    15     while(T--)
    16     {
    17         cin>>n>>s>>t;
    18         int cnt=0;
    19         for(int i=0;i<n;i++)
    20         {   //i=0是有单个字符这种特殊情况
    21             if((i==0 || s[i-1]==t[i-1]) && s[i]!=t[i]) cnt++;
    22         }
    23         
    24         if(cnt>2) cout<<"0"<<endl;
    25         else if(cnt==2) cout<<"6"<<endl;
    26         else if(cnt==1) cout<<ll(2*n-2)<<endl;
    27         else cout<<ll(n*(n+1)/2)<<endl;
    28     }
    29 }

    Plants vs. Zombieszoj4062

    最小值最大化,典型的二分答案

    关键是judge函数怎么写

    除此之外,写出judge也很难ac,此题尽是坑点,写的我一把辛酸泪啊QAQ~~

    什么最后一个要特判,不加次数。。

    什么很容易超ll。。

    什么负数。。

    什么超时。。

    都要及时跳出才行

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1e5+10;
     7 
     8 int n;
     9 ll m;
    10 ll a[maxn],d[maxn];
    11 
    12 ll judge(ll k)
    13 {
    14     //memset(d,0,(n+1)*sizeof(ll));
    15     //memset(d,0,sizeof(d));//1520ms
    16     for(int i=0;i<=n+1;i++) d[i]=0;//630ms
    17     
    18     ll cnt=0;
    19     for(int i=1;i<=n;i++)
    20     {
    21         if(i==n && d[i]>=k) break;//坑点1,最后一个特判
    22         
    23         cnt++; d[i]+=a[i];//注意这个细节,d[i]+=a[i]要放到continue前面,后面必错!(先把每一步必须的一步加上,不要和后面的放在一起算,不容易错)
    24         if(d[i]>=k) continue;//坑点2,不要一直加,会超ll,同时关键防止了下面负数情况!!
    25         //d[i]+=a[i];//之前以为放这一直错QAQ
    26         
    27         ll c=(k-d[i])/a[i];//坑点3,这里(通过上面continue)要防止了过大变负数
    28         if((k-d[i])%a[i]) c++;
    29         cnt+=2*c;
    30         d[i]+=c*a[i];
    31         d[i+1]+=c*a[i+1];
    32         
    33         if(cnt>m) break;
    34     }
    35     return cnt;
    36 }
    37 
    38 int main()
    39 {
    40     ios::sync_with_stdio(0);
    41     cin.tie(0);
    42 
    43     int T;
    44     cin>>T;
    45     while(T--)
    46     {
    47         cin>>n>>m;
    48         ll mn=1e5+10;
    49         for(int i=1;i<=n;i++) cin>>a[i], mn=min(mn,a[i]);
    50 
    51         ll l=0, r=mn*m,ans=0;
    52         while(l<=r)
    53         {
    54             ll mid=(l+r)>>1;
    55             if(judge(mid)<=m) 
    56             {
    57                 ans=mid;
    58                 l=mid+1;
    59             }
    60             else r=mid-1;
    61         }
    62         cout<<ans<<endl;
    63     }
    64 }

    Books,zoj4067

    略难的贪心,分清楚3种情况即可(况且样例都给你了,解释的清清楚楚名明明白白QAQ) 

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const ll maxn=1e5+10;
     7 const ll inf=1e9+5;
     8 ll T,n,m;
     9 ll a[maxn];
    10 
    11 int main()
    12 {
    13     ios::sync_with_stdio(0); cin.tie(0);
    14 
    15     cin>>T;
    16     while(T--)
    17     {
    18         cin>>n>>m;
    19         ll cnt0=0;
    20         for(int i=1;i<=n;i++)
    21         {
    22             cin>>a[i];
    23             if(a[i]==0) cnt0++;
    24         }
    25 
    26         if(m>=n) cout<<"Richman"<<endl;
    27         else if(cnt0>m) cout<<"Impossible"<<endl;
    28         else
    29         {
    30             m-=cnt0;//贪心肯定先选m为0的书籍
    31             ll mn=inf,ans=0;
    32             for(int i=1;i<=n;i++)
    33             {
    34                 if(a[i]==0) continue;//因为为0的书籍已经挑过了,前面m-=cnt0!