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!
    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 }

    完。

  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/redblackk/p/9999184.html
Copyright © 2011-2022 走看看