【日记】12.18

12.18

CF GlobalRound 6

可惜Efst了,不然估计能直接上紫。

A.Competitive Programmer

题意:给一个数,问是否存在其一个排列,使得是60的倍数?

思路:60倍数--含0且为6的倍数--含一个0且数位和为3且是2的倍数--含1个0且数位和为3且又含一个02468

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
char s[M];
int main(){
    int n;
    scanf("%d",&n);
    for(int z=1;z<=n;++z){
        scanf("%s",s);
        int len=strlen(s),sum=0;
        int vou=0,v0=0;
        for(int i=0;i<len;++i){
            if (s[i]=='0')
                ++v0;
            else if ((s[i]-'0')%2==0)
                ++vou;
            sum+=s[i]-'0';
        }
        if (((v0>=2)||(v0&&vou))&&sum%3==0)
            printf("red\n");
        else
            printf("cyan\n");
    }
    return 0;
}

B.Dice Tower

题意:一堆骰子可以堆在地面上,露出来的部分是四周和最上面那一个。现在给定一个数,问是否存在一种堆骰子的方法,使得露出来的部分的和等于这个数?

题解:除了最上面的,每个骰子均贡献14。而最上面的数可能是123456。因此n%14=1-6均可。但要特判1-6是不行的。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
    int n;
    scanf("%d",&n);
    for(int z=1;z<=n;++z){
        LL c;
        scanf("%I64d",&c);
        if ((c/14)&&(1<=c%14&&c%14<=6))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

C.Diverse Matrix

题意:给一个r*c的矩阵,对应的b数组为各行+各列的数的gcd。一个矩阵是diverse的,即b数组各数均不相同。一个矩阵的magnitude=b数组中的最大值,问给定r和c,构造一个magnitude最小的矩阵,并输出。

思路:最小的情况是b数组恰好为1-r+c这些数,则magnitude为r+c,这是最小的情况。下面思考怎么去构造这个矩阵。有一个易于理解的性质,即对于任一k>=1,有gcd(k,k+1)=1。因此我们指定A[i][j]=R[i]C[i],其中R={1,2,3,……,r},C={r+1,r+2,……,r+c}即可满足条件。因为每一列都是对应的b数组中的值乘一堆连续的数,其gcd必然等于对应的b数组中的值,则满足题意。

需要注意r=1或者c=1的情况,此时必须是宽度为1的那个数的关键值为1,不然会出错。

即1*4的矩阵必须是2 3 4 5,不能是5 10 15 20。

#include<bits/stdc++.h>
using namespace std;
const int M=600;
int a[M][M],R[M],C[M];
int main(){
    int r,c;
    scanf("%d%d",&r,&c);
    if (r==1&&c==1){
        printf("0\n");
        return 0;
    }
    int cnt=0;
    if (r<c){
        for(int i=1;i<=r;++i)
            R[i]=++cnt;
        for(int i=1;i<=c;++i)
            C[i]=++cnt;
    }
    else{
        for(int i=1;i<=c;++i)
            C[i]=++cnt;
        for(int i=1;i<=r;++i)
            R[i]=++cnt;
    }
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
            a[i][j]=R[i]*C[j];
    for(int i=1;i<=r;++i){
        for(int j=1;j<=c-1;++j)
            printf("%d ",a[i][j]);
        printf("%d\n",a[i][c]);
    }
    return 0;
}

D.Decreasing Debts

题意:有n个人,互相欠债,问可否优化,使得债务总和最小,不需要保证债务牵扯的人最少。输出优化后的债务关系。

思路:这个题其实很思博……直接计算出每个人的净收益,这种情况下就是债务总和最小(绝对值和/2),之后随便连边就行了,每次保证耗尽一个关系即可。

扫描二维码关注公众号,回复: 8270587 查看本文章
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
struct E{
    int u,v,w;
    E(int a=0,int b=0,int c=0):u(a),v(b),w(c){}
};
queue<int> upd;
queue<int> pnt[M][2];
vector<E> edge;
int vis[M];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        int u,v,d;
        scanf("%d%d%d",&u,&v,&d),edge.push_back(E(u,v,d));
        pnt[u][0].push_back(edge.size()-1),pnt[v][1].push_back(edge.size()-1);
    }
    for(int i=1;i<=n;++i)
        vis[i]=1,upd.push(i);
    while(!upd.empty())
        if (!pnt[i][0].empty()&&!pnt[i][1].empty()){
            while(!pnt[i][0].empty()&&edge[pnt[i][0].front().w==0])
                pnt[i][0].pop();
        }
    return 0;
}

E. Spaceship Solitaire

题意:n种资源,每种资源均至少\(a_i\)时获胜。每天只能生产一种资源的一个单位。但有一些奖励,每个奖励都是t,s,u,即拥有了\(t_j\)但在的\(s_j\)资源时,即可获得一单位\(u_j\)资源。现每次修改一个奖励或者删除/增加一个奖励,每次输出最少几回合胜利。

题解:fst了。我的思路是,每一个bonus一定都用得上,所以只需要记录一下除了所有bonus之外,还需要加多少个资源。回头再补了。

猜你喜欢

转载自www.cnblogs.com/diorvh/p/12078792.html