欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces Global Round 8 (A,B,C,D,F)题解

程序员文章站 2022-04-13 11:43:41
...

一段时间没训练了,状态就是下滑了。。。
一场很可惜的cf。。。

比赛链接

								A  C+=

Codeforces Global Round 8 (A,B,C,D,F)题解
大意:

最初给你两个数a,b,和一个数n;
你可以进行任意操作,每次操作包含两种情况 a+=b,b+=a。
问你你最少经过几次操做可以a,b中出现一个严格大于n的数。

思路:
首先可以发现a,b的值可以互换而没有影响,然后我就让b为a,b中最大的那个数。
然后再发现,你如果只进行一次操作,会出现两种情况
1 (a,a+b);
2 (b,a+b);
很明显操作2更优,然后就是每次操作都选操作二就行了,复杂度大约是log级别的。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+15;
typedef long long ll;
int main()
{
    ll t,b,a,n;
    cin>>t;
    while(t--)
    {
        ll cnt=0;
        cin>>a>>b>>n;
        if(a>b)
            swap(a,b);
        if(a>n)
        {
            cout<<"0"<<endl;
            continue;
        }
        if(a+b>n)
        {
            //cnt++;
            cout<<"1"<<endl;
            continue;
        }
        if(a+2*b>n)
        {
            //cnt++;
            cout<<"2"<<endl;
            continue;
        }
        while(1)
        {
            cnt+=2;
            ll c=a+2*b;
            a=a+b;
            b=c;
            if(a+b>n)
            {
                //cnt++;
                cout<<(1+cnt)<<endl;
                break;//continue;
            }
            if(a+2*b>n)
            {
                //cnt++;
                cout<<(2+cnt)<<endl;
                break;//continue;
            }
        }
    }
    return 0;
}
					B. Codeforces Subsequences

Codeforces Global Round 8 (A,B,C,D,F)题解

状态太差在这里卡了好久,因为预处理范围弄小了,好像上一场也出现这种情况了,
以后写题要认真一些,不能只是抱着先验证思路的状态,而是刚开始就认真对待它。

题意:
给你一个k,你要找到一个字符串,其中有最少k个子序列是codeforces。

思路:
codeforces 有1个
codeforcess 有2个
codeforceess 有4个
codeforcceess 有8个

ccooddeeffoorrcceesss有(512*3=1536)个。

规律就是这样。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e2+15;
typedef long long ll;
ll f[N][N];
int main()
{
    ll t,b,a,n,k;
    for(int i=1;i<=100;i++)
    {
        f[i][0]=1;
        for(int j=1;j<=100;j++)
        {
            f[i][j]=f[i][j-1]*i;
        }
    }
    char str[100];
    str[1]='c';
    str[2]='o';
    str[3]='d';
    str[4]='e';
    str[5]='f';
    str[6]='o';
    str[7]='r';
    str[8]='c';
    str[9]='e';
    str[10]='s';
    cin>>k;
    if(k==1)
    {
        cout<<"codeforces"<<endl;   return 0;
    }
    if(k<=2)
    {
        cout<<"codeforcess"<<endl;   return 0;
    }
    if(k<=4)
    {
        cout<<"codeforceess"<<endl;   return 0;
    }
    for(int i=1;i<=100;i++)
    {
        if(f[i][10]>k)
        {
            for(int j=10;j>=0;j--)
            {
                ll op=f[i-1][j]*f[i][10-j];
                if(op>=k)
                {
                    for(int l=1;l<=j;l++)
                    {
                        for(int r=1;r<=i-1;r++)
                            cout<<str[l];
                    }
                    for(int l=j+1;l<=10;l++)
                    {
                        for(int r=1;r<=i;r++)
                            cout<<str[l];
                    }
                    cout<<endl;
                    return 0;
                }
            }
        }
    }
    return 0;
}
						C. Even Picture

Codeforces Global Round 8 (A,B,C,D,F)题解
Codeforces Global Round 8 (A,B,C,D,F)题解

	C也是一个很烦的题,这场真的好多我不喜欢的题呀。。。。

题意:你有一个包含很多个格子的图,你可以把一些格子涂成黑色。
但是你在涂色的时候有一些要求
1 所有灰色格子都是任意可达的,即灰色格子都是联通的。
2 每个灰色格子的邻居中,灰色格子的数量是偶数。
然后给你一个数n,n的意义是上下左右都是灰色格子的格子数。
让你把这个图构造出来
思路:
首先手玩n=1,n=2,n=3 。请看图
Codeforces Global Round 8 (A,B,C,D,F)题解
然后规律就是这样,不过我实现了很久,因为现在不是很喜欢写代码。。。(感觉有必要练一练模拟了)。。。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+15;
typedef long long ll;
ll p[N],vis[N],a[N];
int main()
{
    ll k;
    cin>>k;
    ll op=k*3+2+10;
    cout<<op<<endl;
    cout<<"0 0"<<endl;
    cout<<"1 0"<<endl;
    cout<<"2 0"<<endl;
    cout<<"0 1"<<endl;
    cout<<"2 1"<<endl;
    cout<<"0 2"<<endl;
    cout<<(k+3)<<" "<<(k+1)<<endl;
    cout<<(k+3)<<" "<<(k+2)<<endl;
    cout<<(k+3)<<" "<<(k+3)<<endl;
 
    cout<<(k+2)<<" "<<(k+3)<<endl;
    cout<<(k+1)<<" "<<(k+3)<<endl;
    cout<<(k+1)<<" "<<(k+2)<<endl;
 
    for(int i=2;i<=k+1;i++)
    {
        cout<<(i-1)<<" "<<(i)<<endl;
        cout<<(i)<<" "<<(i)<<endl;
        cout<<(i+1)<<" "<<(i)<<endl;
    }
 
    return 0;
}
					D. AND, OR and square sum

Codeforces Global Round 8 (A,B,C,D,F)题解
题意:
给你一个数n,和 n个数 。
你可以进行任意次操作。
每次操作就是找两个数x,y; 让x = x | y , y = y & x ;
问你 你选择最好的策略来操作,得到的最大的他们这些数的平方之和是多少。

思路:
首先想到
如果x=1,y=1,那么经过一次操作后无影响。
如果x=0,y=0,那么经过一次操作后无影响。
如果x=1,y=0,那么经过一次操作后无影响。
如果x=0,y=1,那么经过一次操作后x=变成1,y变成0。
然后发现这对于所有的二进制对应位数都一样。
然后就想到这代表可以在二进制情况下任意交换0和1。
然后记录二进制下每一位上1的个数,贪心的一直构造目前所能构造的最大数就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+15;
typedef long long ll;
ll p[N],vis[N],a[N];
int main()
{
    ll n;
    p[0]=1;
    for(int i=1;i<=25;i++)
    {
        p[i]=p[i-1]*2;
    }
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        ll x=a[i];
        for(int j=0;j<=23;j++)
        {
            if(x&p[j])
                vis[j]++;
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        ll x=0;
        for(int j=0;j<=23;j++)
        {
            if(vis[j]>0)
            {
                vis[j]--;
                x=x|p[j];
            }
        }
        ans+=x*x;
    }
    cout<<ans<<endl;
    return 0;
}
						F. Lamps on a Circle

Codeforces Global Round 8 (A,B,C,D,F)题解
Codeforces Global Round 8 (A,B,C,D,F)题解

写的第一道交互题。	
思路很好想,不过格式出了点问题。
以后应该不再烦交互题了。

题意:
刚开始有n盏灯围成一个环,你和imp轮流玩游戏,回合制操作,你先手。
每次轮到你操作,你可以选择结束游戏,或者继续玩下去。
继续玩下去的话你就先选择一个数k,然后选择k盏灯把他们点亮,对于本来就亮着的无影响。
然后imp操作,他选择一个数x,然后从x开始,顺时针关掉k盏灯,对于本来就关着的也无影响。
你想让开着的灯的数量最大,imp想让关着的灯的数量最大。
imp很聪明,你也是。
然后你经过若干次轮回后会得到最大的灯可以亮着的数量。然后结束。

思路:
先看这些
n=5,10100 ,可以亮两盏
n=7,1010100,亮三盏。
n=13,1110111011100,亮9盏。
n=15,111011101110110,亮8盏。
然后就很显然,最终情况都是这样的,你找到一个数k,它亮k-1盏,关1盏,亮k-1盏,关1盏。。。一直到结尾特判。
然后怎么寻找k呢?
你如果选择k,会得到的最大数量是(k-1)*n/k - (k-1)
然后你如果选择k+1,会得到的最大数量是(k)*n/(k+1)-k;
比较选择k可以获得的最大数量和选择k+1获得的最大数量。
就是比较(k-1)*n/k - (k-1) 和 (k)*n/(k+1)-k 的大小。
用减法,来比较,化简后得到 下面式子:
k · (k+1) > n;
找到第一个k 就行,因为k再变大的话数量也会出现衰减。
然后代码写起来也还行,不过我那时以为imp会一直做最优决策,但发现并不是,这就是交互提吧,需要加个特判。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+15;
typedef long long ll;
int main()
{
    ll n,d;
    cin>>n;
    if(n<=3){
        cout<<"0"<<endl;
        return 0;
    }
    for(d=1;;d++)
        if(d*(d+1)>n)
            break;
    ll op=d+1,x=1;
    for(ll i=1;;i++){
        if(op>=n)
            break;
        cout<<d<<" ";
        for(int j=1;j<=d-1;j++){
            if(x+j-1<=n)
                cout<<(x+j-1)<<" ";
            else
                cout<<(x+j-1-n)<<" ";
        }
        ll lx=x+d-2;
        if(lx>op)
            cout<<(x-1)<<endl;
        else
            cout<<op<<endl;
        op++;
        if(op%d==0)
            op++;
        cin>>x;
    }
    cout<<"0"<<endl;
    return 0;
}
 
相关标签: codeforces 思维