• Codeforces 每日一练 735D+573B+374C


    735D Taxes

    传送门
    镜像传送门
    数论题(1600)
    Mr. Funt有收入为n,他为了减少自己需要缴纳的税额(DD行为),想要把收入分成k份(每份收入>1),每份单独缴税。对于每份收入,需要缴纳的税款为其最大因子(不为自己,如果是质数就是1)。帮助Mr. Funt最小化他缴纳的税款。
    首先如果n为质数就可以不分了,1一定是最小的。
    对于偶数,结果必定大于等于2,分两个质数就是2,分一个两个偶数就大于2,根据哥德巴赫猜想,任一大于2的偶数都可写成两个素数之和,那么偶数的答案就是2。
    对于奇数,必定会分成一奇一偶,而偶数小于等于2(2的情况为1),而且一定可以找到一个质数充当分出来的质数,那么奇数的答案就是小于等于3,如果奇数-2为质数,那么就取最小值2,其他情况为3.
    (就当补充知识树了~~

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define IOS ios_base::sync_with_stdio(false);cin.tie(0);
    #define maxn 5005
    #define inf 1000000002
    #define for_(i,n) for(ll (i)=1;(i)<=(n);i++)
    #define mod 80112002
    int n,m;
    int is_prome(int n){
        for (int i = 2; i <=sqrt(n) ; ++i) {
            if(n%i==0)return 0;
        }
        return 1;
    }
    int main(){
        IOS
        cin>>n;
        if(is_prome(n)){cout<<1;return 0;}
        if(n%2==0)cout<<2;
        else{
            if(is_prome(n-2))cout<<2;
            else cout<<3;
        }
        return 0;
    }
    

    573B Bear and Blocks

    传送门
    镜像传送门
    dp水题(迫真
    1800
    Limak是只小熊,他堆了一行塔,每座塔都有相应的高度,每次Limak可以把所有没有被完全包围的砖块摧毁,询问要多少次才能将所有塔摧毁(tm熊的力量!(滑稽))
    什么是完全包围呢,如图:
    在这里插入图片描述
    (黑色部分即为被完全包围的砖块。)
    根据题意,我们可以很快得到几条规律:
    1、高度为1的在第1轮就毁掉
    2、第i座塔最多存活h[i]轮(每座塔最上面的砖块每轮必被摧毁)
    3、从左向右扫,第i+1座塔最多比第i座塔多存活1轮,从右向左同理
    现在转移方程就很好写了,开两个数组存分别存从左到右和从右到左(规律3)每座塔的存活轮数,那每个塔的存活轮数就是两个数组中对应位置的最小值,最后遍历每座塔取一个最大值就好了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define IOS ios_base::sync_with_stdio(false);cin.tie(0);
    #define maxn 100005
    #define inf 1000000002
    #define for_(i,n) for(ll (i)=1;(i)<=(n);i++)
    #define mod 80112002
    int n;
    int h[maxn],l[maxn],r[maxn];
    int main(){
        IOS
        cin>>n;
        for_(i,n)cin>>h[i];
        l[1]=r[n]=1;
        for_(i,n){
            if(i==1)continue;
            if(h[i]==1){
                l[i]=1;
            }else{
                l[i]=l[i-1]+1;
            }
            l[i]=min(l[i],h[i]);
        }
        for (int j = n-1; j >=1 ; --j) {
            if(h[j]==1)r[j]=1;
            else r[j]=r[j+1]+1;
            r[j]=min(r[j],h[j]);
        }
        int ans=-1;
        for_(i,n){
            //cout<<l[i]<<" "<<r[i]<<endl;
            ans=max(ans,min(l[i],r[i]));
        }
        cout<<ans;
        return 0;
    }
    

    374C Inna and Dima

    点这里去这道题恰狗粮
    点这里去恰镜像狗粮
    dfs+dp(2000)
    Inna和Dima买了一张n*m的桌子,每个格子里都写有D、I、M、A中某个字母,Inna特别爱Dima,所以Inna想从某个D开始按照D-I-M-A-D-I……的顺序经过尽量多完整的“DIMA”,如果一个都没有,那么输出“Poor Dima!”,如果可以一直走下去(存在环),输出“Poor Inna!”,否则输出最多能走的个数。
    先处理给的方格图,对走向合法的组合连单向边,开个dp存到当前节点的最长路径长度,然后从每个D开始dfs就好,但是会T,加个剪枝就好了,如果下一个节点的dp可以更新,就dfs下一个节点。最后取所有A的最大值除以4即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define IOS ios_base::sync_with_stdio(false);cin.tie(0);
    #define maxn 1005
    #define inf 1000000002
    #define for_(i,n) for(ll (i)=1;(i)<=(n);i++)
    #define mod 80112002
    int dir[4]={1,-1,0,0},dir2[4]={0,0,1,-1};
    int n,m;
    struct node{
        int x,y;
    };
    node cc[maxn*maxn];
    vector<int> g[maxn*maxn];
    int d[maxn*maxn],num[maxn][maxn],vis[maxn*maxn],dp[maxn*maxn];
    char s[maxn][maxn];
    void link(int v){
        int x=cc[v].x,y=cc[v].y;
        for (int i = 0; i <4 ; ++i) {
            if(x+dir[i]<1||x+dir[i]>n||y+dir2[i]<1||y+dir2[i]>m)continue;
            int u=num[x+dir[i]][y+dir2[i]];
            if(s[x][y]=='D'&&s[x+dir[i]][y+dir2[i]]=='I'){g[v].push_back(u);d[u]++;}
            if(s[x][y]=='I'&&s[x+dir[i]][y+dir2[i]]=='M'){g[v].push_back(u);d[u]++;}
            if(s[x][y]=='M'&&s[x+dir[i]][y+dir2[i]]=='A'){g[v].push_back(u);d[u]++;}
            if(s[x][y]=='A'&&s[x+dir[i]][y+dir2[i]]=='D'){g[v].push_back(u);d[u]++;}
        }
    }
    void dfs(int x){
        vis[x]=1;
        for (auto i:g[x]){
            if(vis[i]&&s[cc[i].x][cc[i].y]=='D'){
                cout<<"Poor Inna!";
                exit(0);
            }
            if(dp[i]<dp[x]+1){
                dp[i]=max(dp[i],dp[x]+1);
                dfs(i);
            }
        }
        vis[x]=0;
    }
    int main(){
        IOS
        cin>>n>>m;
        for_(i,n)cin>>(s[i]+1);
        int cnt=1;
        for_(i,n){
            for_(j,m){
                num[i][j]=cnt;
                cc[cnt].y=j;
                cc[cnt++].x=i;
            }
        }
        for_(i,cnt){link(i);}
        queue<int> q;
        for_(i,cnt){
            if(s[cc[i].x][cc[i].y]=='D'){dp[i]=1;q.push(i);}
        }
        while(!q.empty()){
            int x=q.front();
            q.pop();
            dfs(x);
        }
        int ans=0;
        for_(i,cnt){
            if(s[cc[i].x][cc[i].y]=='A')ans=max(ans,dp[i]);
        }
        if(ans==0){cout<<"Poor Dima!";return 0;}
        cout<<ans/4;
        return 0;
    }
    
  • 相关阅读:
    Mac终端运行java程序
    Mac上csv导入mysql提示错误[Error Code] 1290
    Mac终端使用mysql
    将spark默认日志log4j替换为logback
    Cocos2d-x 3.x部署到安卓
    Cocos2d-x 3.0 场景切换
    visual studio 未将对象引用设置到对象的实例
    C++ list用法
    减而治之
    递归
  • 原文地址:https://www.cnblogs.com/Bazoka13/p/12623394.html
Copyright © 2020-2023  润新知