Codeforces Round #392 (Div. 2)

来源:互联网 发布:华兴资本 知乎 编辑:程序博客网 时间:2024/06/03 16:14

A - Holiday Of Equality(water)

题意:

  一共给你N个数,让你向上补数值,使得最终所有数值都相等,输出最少花费。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 100 + 5;int a[maxn];int main(){    int n;    scanf("%d", &n);    int maxx = -INF;    for(int i = 0; i <n; i++)    {        scanf("%d", &a[i]);        if(a[i] > maxx) maxx = a[i];    }    int sum = 0;    for(int i = 0; i < n; i++)    {        sum += maxx - a[i];    }    cout << sum << endl;    return 0;}


B - Blown Garland(杂?)

题意:

  一共有四种颜色的灯RBYG,现在有!处表示这个位子的灯泡坏掉了,我们现在需要在!处放置四种颜色的灯泡,使得最终的序列,保证每连续的四个灯泡都具有四种不同的颜色。问我们需要添加多少个R,B,Y,G.保证答案唯一。

思路:

  神特么这题一开始卡住不知道怎么写好。然后抓着前四个点确定,则整串都确定的特点。。直接几个for一套暴力掉了,反正没多大。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 100 + 5;char s[maxn], ss[maxn];int vis[10];int r,y,g,b;char p[] = {'R', 'B', 'Y', 'G'};void solve(char ss[]){    for(int i = 4; i < strlen(s); i++)    {        ss[i] = ss[i - 4];    }    int cntr = 0, cnty = 0, cntg = 0, cntb = 0;    for(int i = 0; i < strlen(s); i++)    {        if(s[i] != '!')        {            if(s[i] != ss[i])            {                return;            }        }        else        {            if(ss[i] == 'R')    cntr++;            else if(ss[i] == 'Y')   cnty ++;            else if(ss[i] == 'G')   cntg++;            else if(ss[i] == 'B')   cntb++;        }    }    r = cntr, y = cnty, g = cntg, b = cntb;}int main(){    scanf("%s", s);    r = 0, b = 0, y = 0, g = 0;    for(int i = 0; i < 4; i++)    {        for(int j = 0; j < 4; j++)        {            for(int k = 0; k < 4; k++)            {                for(int l = 0; l < 4; l++)                {                    ss[0] = p[i], ss[1] = p[j], ss[2] = p[k], ss[3] = p[l];                    solve(ss);                }            }        }    }    cout << r << " " << b << " " <<  y << " " << g << endl;    return 0;}

  其实可以这样想,任意四个点确定,则整个序列确定,那么对于i%4来说,余数相同的位置的颜色必然相同啊。= =。╮(╯▽╰)╭真是撒比lity。

 

#include <bits/stdc++.h>using namespace std;char ch[128];int cnt[5];int main(){    char s[105];    scanf("%s", s);    int len = strlen(s);    for(int i = 0; i < len; i++)    {        if(s[i] != '!')        {            ch[s[i]] = i % 4;        }    }    for(int i = 0; i < len; i++)    {        if(s[i] == '!') cnt[i % 4]++;    }    printf("%d %d %d %d\n", cnt[ch['R']], cnt[ch['B']], cnt[ch['Y']], cnt[ch['G']]);    return 0;}

C - Unfair Poll(数学)

题意:

  教室里有n列m排,老师上课点名从第一列第一排开始往后点,直到点到第一列第m排,就从第二列第一排开始点,当点完第n列的名之后,接着点第n-1列的名。以此类推,就是从列上来看的话:1,2,3,4,……,n,n-1,n-2,……,1,2,……。这样的顺序点名。老师上课总共点k次名,问该课堂最多可以点同一个同学多少次,最少可以点同一个同学多少次,点了位置为(x,y)的同学多少次名。

思路:

  直接推公式的做法:

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 100 + 5;LL n, m, k, x, y;int main(){    LL maxx = 0, minn = INF, special = 0;    cin >> n >> m >> k >> x >> y;    if(n == 1)    {        LL times = k / m;        LL mod = k % m;        maxx = times + (mod != 0);        minn = times;        special = times + (y <= mod);    }    else if(n == 2)    {        LL times = k / (2 * m);        LL mod = k % (2 * m);        maxx = times + (mod != 0);        minn = times;        special = times + ((x - 1) * m + y <= mod);    }    else    {        if(k <= n * m)        {            maxx = 1;            minn = ((n * m) == k);            if((x - 1) * m + y <= k)            {                special = 1;            }        }        else        {            LL times = k / ((2 * n - 2) * m);            LL mod = k % ((2 * n - 2) * m);            if(mod > n * m)            {                minn = times + 1;                maxx =  2 * times + 2;                if(x == 1 || x == n)                {                    special = times + 1;                }                else                {                    special = times * 2 + 1 + (( (n - 1 - x) * m + y ) <= (mod - n * m));                }            }            else            {                minn = times + (mod == (n * m));                maxx = 2 * times + (mod > m);                if(x == 1 || x == n)                {                    special = times +( ( (x - 1) * m + y ) <= (mod) );                }                else                {                    special = times * 2 + (( (x - 1) * m + y ) <= (mod));                }            }        }    }    cout << maxx << " " << minn << " " << special << endl;    return 0;}

  直接推公式容易错,如果复杂度允许的话,使用一定的模拟去替换,比较不容易错。拿别人的代码,体会下这种感觉就好。

int main(void){    int i, j;    cin>>n>>m>>k>>x>>y;    if(n==1)    {        for(i=1 ; i<=n ; i++)        {            for(j=1 ; j<=m ; j++)            {                val[i][j]+=k/m;            }        }        k%=m;        for(i=1 ; i<=n ; i++)        {            for(j=1 ; j<=k ; j++)            {                val[i][j]++;            }        }    }    else    {        for(i=1 ; i<=n ; i++)        {            for(j=1 ; j<=m ; j++)            {                val[i][j]+=k/((2*n-2)*m);                if(i!=1 && i!=n)                {                    val[i][j]+=k/((2*n-2)*m);                }            }        }            k=k%((2*n-2)*m);        for(i=1 ; i<=n ; i++)        {            for(j=1 ; j<=m ; j++)            {                if(k>0)                {                    val[i][j]++;                    k--;                }            }            }            for(i=n-1 ; i>=1 ; i--)        {            for(j=1 ; j<=m ; j++)            {                if(k>0)                {                    val[i][j]++;                    k--;                }            }        }    }    for(i=1 ; i<=n ; i++)    {        for(j=1 ; j<=m ; j++)        {            ansf=max(ansf,val[i][j]);            anss=min(anss,val[i][j]);        }    }    cout<<ansf<<" "<<anss<<" "<<val[x][y];}

D - Ability To Convert

题意:

  给出一个进制数n,还有一个值,是数字k在n进制下的值,求k的最小值。


E - Broken Tree

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 2e5 + 5;LL sum[maxn];vector<int>G[maxn];struct node{    LL w, p, delta;    subtract(LL temp)    {        w -= temp;        p -= temp;        delta += temp;    }}toNodes[maxn];void dfsSubtract(int u, int pa)//返回子树的重量{    sum[u] = 0;    for(auto v : G[u]) if(v != pa)    {        dfsSubtract(v, u);        LL temp = min(toNodes[v].p, min(toNodes[v].w - 1, toNodes[v].p - sum[v]));        sum[u] += sum[v];        if(temp < 0)        {            puts("-1");            exit(0);        }        toNodes[v].subtract(temp);        sum[u] += toNodes[v].w;    }}LL dfsAdd(int u, LL d){    LL used = 0;    for(auto v : G[u])    {        LL addBack = min(toNodes[v].delta, d);        toNodes[v].w += addBack;        toNodes[v].p += addBack;        d -= addBack;        used += addBack;        LL temp = dfsAdd(v, min(d, toNodes[v].p - sum[v]));        d -= temp;        used += temp;    }    return used;}int main(){    int n;    scanf("%d", &n);    vector<pair<int, int>>ans;    for(int i = 0; i < n - 1; i++)    {        int u, v, w, p;        scanf("%d%d%d%d", &u, &v, &w, &p);        G[u].push_back(v);        toNodes[v] = {w, p, 0};        ans.push_back({u, v});    }    dfsSubtract(1, 0);    toNodes[1].p = 1LL << 60;    dfsAdd(1, 1LL << 60);    printf("%d\n", n);    for(auto o : ans)    {        printf("%d %d %I64d %I64d\n", o.first, o.second, toNodes[o.second].w, toNodes[o.second].p);    }    return 0;}


F - Geometrical Progression



#include <bits/stdc++.h>using namespace std;typedef long long LL;LL quickPow(LL a, LL b){    LL ret = 1;    while(b)    {        if(b & 1)   ret = ret * a;        b >>= 1;        a = a * a;    }    return ret;}int main(){    int n, l, r;    scanf("%d%d%d", &n, &l, &r);    LL ans = 0;    if(n == 1)    {        ans = r - l + 1;    }    else if(n == 2)    {        ans = 1LL * (r - l + 1) * (r - l);    }    else if(n > 24)//....24的时候还是有解的 因为是极限是2^(n-1),而不是2^n。 = =简直了。    {        ans = 0;    }    else    {        LL up = pow(2, log2(1e7 + 5) / (n - 1));//因为有一个约束条件l * d ^ (n - 1) <= r 可以理解成公比d<=log2(1e7)        for(LL q = 1; q <= up; q++)        {            for(LL p = q + 1; p <= up; p++)            {                if(__gcd(p, q) == 1)                {                    LL pn = quickPow(p, n - 1);                    LL qn = quickPow(q, n - 1);                    if(1LL * l * pn / qn > r)   continue;                    ans += (r * qn / pn) / qn - (l - 1) / qn;                }            }        }        ans = ans * 2;    }    cout << ans << endl;    return 0;}



0 0