Codeforces Round #369

A题

一个大水题,就是找字符串里有没有两个连续的O,如果有把OO改成++
代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,ans;
string s[1001];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        cin>>s[i];
    }
    for(int i=1;i<=n;i++){
        if(s[i][0]=='O'&&s[i][1]=='O'){
            cout<<"YES"<<endl;
            s[i][0]='+';
            s[i][1]='+';
            for(int i=1;i<=n;i++){
                cout<<s[i]<<endl; 
            }
            return 0; 
        }
        if(s[i][3]=='O'&&s[i][4]=='O'){
            cout<<"YES"<<endl;
            s[i][3]='+';
            s[i][4]='+';
            for(int i=1;i<=n;i++){
                cout<<s[i]<<endl; 
            }
            return 0; 
        }
    }
    cout<<"NO";
    return 0;
} 

B题

很显然,看到这题我想到了一道大水题 神奇的幻方 就是在幻方中填一个数是横竖斜都相等。这本来是一道水题啊。。可是我最终FST掉了。。。
这是zzs神犇的代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <climits>

#ifdef DEBUG
#include <cassert>
#include <cstdarg>
#endif

#include <iostream>
#include <algorithm>
#include <utility>

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>

#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/algorithm>
#include <ext/rope>

#define REP(i,n) for(i=0;i<(n);i++)
#define REP_B(i,n) for(i=1;i<=(n);i++)
#define CUS_REP(i,a,b) for(i=(a);i<(b);i++)
#define CUS_REP_B(i,a,b) for(i=(a);i<=(b);i++)
#define GRAPH_REP(i,u) for(i=first[u];i;i=next[i])
#ifdef DEBUG
#define PNT_DEBUG(...) fprintf(stderr,__VA_ARGS__)
#endif
const int maxn=501;
long long A[maxn][maxn];
inline bool check(int n){
    long long sum,last_sum;
    last_sum=0;
    register int i,j;
    for(i=1;i<=n;i++)
        last_sum+=A[1][i];
    for(i=2;i<=n;i++){
        sum=0;
        for(j=1;j<=n;j++)
            sum+=A[i][j];
        if(sum!=last_sum)
            return false;
        last_sum=sum;
    }
    for(i=1;i<=n;i++){
        sum=0;
        for(j=1;j<=n;j++)
            sum+=A[j][i];
        if(sum!=last_sum)
            return false;
        last_sum=sum;
    }
    sum=0;
    for(i=1;i<=n;i++){
        sum+=A[i][i];
    }
    if(sum!=last_sum)
        return false;
    sum=0;
    for(i=n;i>=1;i--)
        sum+=A[i][n-i+1];
    if(sum!=last_sum)
        return false;
    return true;
}
int main(){
    int n;
    register int i,j,a,b;
    long long t1,t2;
    scanf("%d",&n);
    REP_B(i,n){
        REP_B(j,n){
            scanf("%I64d",&A[i][j]);
            if(A[i][j]==0){
                a=i;
                b=j;
            }
        }
    }
    long long x;
    t1=0;t2=0;
    if(n==1){
        puts("1");
        return 0;
    }
    if(a==1){
        for(i=1;i<=n;i++){
            t1+=A[2][i];
            t2+=A[1][i];
        }
        x=t1-t2;
        A[a][b]=x;
        if(check(n) && x>=1){
            printf("%I64d\n",x);
        }else{
            puts("-1");
        }
    }else{
        for(i=1;i<=n;i++){
            t1+=A[a-1][i];
            t2+=A[a][i];
        }
        x=t1-t2;
        A[a][b]=x;
        if(check(n) && x>=1){
            printf("%I64d\n",x);
        }else{
            puts("-1");
        }
    }
    return 0;
}

C题

刚看我还以为要用brute force来搞,结果敲完暴力发现这是n^m的算法。。。根本过不了。。之后发现可以dp乱♂搞?于是撸了一发dp,复杂度(nm)^2,n、m的范围都有100,所以我本来没以为他能过。。神犇zzs说要用优先队列来♂搞,于是就把代码锁掉了。。。本题有一个巨坑,就是要用long long于是就来hack一下,虽说没有hack到人,但是发现房间里很多用的dp。。。有的还用了暴力通过了前测(真是exciting)不过时限是两秒,差不多能过吧到最后果然Accept了。
代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define inf 999999999999 
using namespace std;
int n,m,k,a[101];
long long ans=0;
long long cl[101][101],f[105][105][105];
int x,y;
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%I64d",&cl[i][j]);
        }
    }
    if(n==1){
        if(k==1){
            if(a[1]==0){
                long long sx=inf;
                for(int i=1;i<=m;i++){
                    sx=min(sx,cl[1][i]);
                }
                printf("%I64d",sx);
                return 0;
            }else{
                printf("0");
                return 0;
            }
        }else{
            printf("-1");
            return 0;
        }
    }
    int l=88888;
    for(int i=1;i<=n;i++){
        if(a[i]==0){
            l=i;
            break;
        }
    }
    if(l==88888){
        ans=1;
        for(int i=2;i<=n;i++){
            if(a[i]!=a[i-1])ans++;
        }
        if(ans==k){
            printf("0");
            return 0;
        } 
        printf("-1");
        return 0;
    }
    for(int i=0;i<=102;i++){
        for(int j=0;j<=102;j++){
            for(int k=0;k<=102;k++){
                f[i][j][k]=inf;
            }
        }
    }
    if(a[1]==0){
        for(int i=1;i<=m;i++){
            f[1][i][1]=cl[1][i];
        }
    }else{
        f[1][a[1]][1]=0;
    }
    for(int i=2;i<=n;i++){
        if(a[i]==0){
            for(int j=1;j<=m;j++){
                for(int k=1;k<=i;k++){
                    long long cur=inf;
                    for(int l=1;l<=m;l++){
                        if(l!=j)
                        cur=min(cur,f[i-1][l][k-1]);                 
                    }
                    f[i][j][k]=min(f[i][j][k],cur+cl[i][j]);
                    f[i][j][k]=min(f[i][j][k],f[i-1][j][k]+cl[i][j]);

                }
            }
        }else{
            for(int k=1;k<=i;k++){
                long long cur=inf;
                for(int l=1;l<=m;l++){
                        if(l!=a[i])
                        cur=min(cur,f[i-1][l][k-1]);                 
                }
                f[i][a[i]][k]=min(f[i][a[i]][k],cur);
                f[i][a[i]][k]=min(f[i][a[i]][k],f[i-1][a[i]][k]);
            }

        }
    }
    ans=inf;
    for(int i=1;i<=m;i++){
        ans=min(ans,f[n][i][k]);
    }
    if(ans==inf){
        printf("-1");
        return 0;
    } 
    printf("%I64d",ans);
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值