• 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!
    35 
    36                 if(m)//如果还有次数的话就选
    37                 {
    38                     ans+=a[i];
    39                     m--;
    40                 }
    41                 else mn=min(mn,a[i]);//从没选过的剩下的里面选一个最小的
    42             }
    43 
    44             ans+=mn-1;
    45             cout<<ans<<endl;
    46         }
    47     }
    48 
    49     return 0;
    50 }

    Function and Function,zoj4070

    签到题,给你的递归形式,但不要一条路到死。递归可以改循环,循环也可以改递归,哪个不爆栈方便用哪个。

    做这题有2点:

    1.做这题关键重点:把它的函数嵌套全部展开,g(x)就变成了次方个f(x)!!从头开始计算就行了。

    2.然后是规律,k辣么大每次都算肯定超市啦,发现0和1的函数值相反正好来回跳,所以到0我们就可以根据剩余次方判断出答案啦!

    (3.有个坑点很容易错,0的函数值是0,必须特判返回1。像其它一样取位正常算的话返回是0。很容易错)

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 typedef long long ll;
     5 ll s[10]={1,0,0,0,1,0,1,0,2,1};
     6 ll T,x,k;
     7 
     8 ll f(ll y)
     9 {
    10     if(y==0) return 1;//坑点,很重要,因为0特殊,下面返回0是错的!
    11 
    12     ll ans=0;
    13     while(y)
    14     {
    15         ans+=s[y%10];
    16         y/=10;
    17     }
    18 
    19     return ans;
    20 }
    21 
    22 int main()
    23 {
    24     //ios::sync_with_stdio(false); cin.tie(0);
    25 
    26     scanf("%lld",&T);
    27     while(T--)
    28     {
    29         scanf("%lld%lld",&x,&k);
    30 
    31         if(k==0) { printf("%lld
    ",x); continue;}
    32 
    33         for(int i=1;i<=k;i++)
    34         {
    35             x=f(x);
    36             if(x==0)
    37             {
    38                 ll t=k-i;
    39                 if(t%2) x=1;
    40                 else x=0;
    41                 break;
    42             }
    43         }
    44         printf("%lld
    ",x);
    45     }
    46 
    47     return 0;
    48 }

    完。

  • 相关阅读:
    javascript深入理解js闭包
    【STL源码学习】STL算法学习之一
    【STL源码学习】细品vector
    【C++深入浅出】智能指针之auto_ptr学习
    【字典树应用】联想用户最想输入的词汇
    【数据结构】非常有用的hash表
    【WIN32进阶之路】:内存映射文件
    【WIN32进阶之路】:线程同步技术纲要
    win32进阶必备:多线程同步之互斥锁
    【C++深入浅出】设计模式学习之单例模式
  • 原文地址:https://www.cnblogs.com/redblackk/p/9999184.html
Copyright © 2020-2023  润新知