Codeforces Round #655 (Div. 2)题解ABCD

A题:
水题,只要全部元素设置为1就行了。
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const int mod=1e9+7;
int main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
    
    
           cout<<1<<" ";
        }
        cout<<endl;
    }
}

B题:
假设a<=b,我们可以发现,当b是a的倍数时,lcm(a,b)会取得最小值,即b=ka。则a+ka=n,(k+1)a=n, k越小,a和b越接近,则b越小,lcm(a,b)也越小。则我们就是要去找n的最小因子(除了1),除掉便是a。
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const int mod=1e9+7;
ll gcd(ll a, ll b)
{
    
    
    if (b == 0)
        return a;
    else if (a < b)
        return gcd(b, a);
    else
        return gcd(b, a % b);
}

ll lcm(ll a, ll b)
{
    
    
    return a / gcd(a, b) * b;
}
int main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n;
        cin>>n;
        if(n==2)
        {
    
    
            cout<<1<<" "<<1<<endl;
            continue;
        }
        if(n==3)
        {
    
    
            cout<<1<<" "<<2<<endl;
            continue;
        }
        int a1,b1;
        int f=-1;
        for(int i=2;i<=sqrt(n);i++)
        {
    
    
            if(n%i==0)
            {
    
    
                f=1;
               a1=n/i;
               b1=n-a1;
               break;
            }
        }
        if(f==1) cout<<min(a1,b1)<<" "<<max(a1,b1)<<endl;
        else cout<<1<<" "<<n-1<<endl;
    }
}

C题:
当数组中全部a[i]=i的时候,答案肯定为0,当只有一段连续区间(l=<i<=r)a[i]!=i时,直接一次操作将区间的数变为a[i]=i,答案为1。当有两段或两段以上的连续区间不满足要求时,我们可以记录下第一段的开头位置L,和最后一段的结尾位置R,使用一次操作,先将最后一段不满足要求的区间变为a[i]=i,从最后一段区间的开头-1位置一直到第一段的开头都可以先变为不满足要求的,之后再使用一次操作,将这段区间变为合法的,那么只需两次便可完成,答案为2。
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<vector>
using namespace std;
#define iis std::ios::sync_with_stdio(false); cin.tie(0)
typedef long long ll;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;

int a[MAXN];
int main()
 {
    
    
 	int t;
 	cin>>t;
 	while(t--)
 	{
    
    
 		int n;
 		cin>>n;
 		for(int i=1;i<=n;i++)
 		{
    
    
 			cin>>a[i];
 		}
 		int ans=0;
 		int f=0;
 		for(int i=1;i<=n;i++)
 		{
    
    
 			if(a[i]!=i)
 			{
    
    
 				if(f==0)
 				{
    
    
 					f=1;
 					ans++;
 				}
 			}
 			else f=0;
 		}
 		if(ans==0) cout<<0<<endl;
 		else if(ans==1) cout<<1<<endl;
 		else cout<<2<<endl;
 	}
 }

D题:
比赛时没写出来,看完大佬的思路,大概是这样,我们假设第i个数字需要保留到最后,那么只看左边,则第i-1的数字必须删掉,一直往左推,到1的时候往左是n,直到只剩下一个数。当i为奇数时,那么可以发现,i前面的偶数位置都会删掉,奇数位置都会保留,i后面奇数位置都会删掉,偶数位置都会保留,反之当i为偶数时,i前面奇数位置都会删掉,i后面偶数位置都会删掉。
比如 1 2 3 4 5 6 7。
当我们选择4保留的时候,那么3删掉—>1 6 5 6 7, 删掉 1---->5 6 13 ,删掉6---->18。
当我们选择5保留的时候,那么4删掉—>1 2 8 6 7, 删掉 2---->6 7 9 ,删掉7---->15。
所以我们枚举要保留的位置,利用前缀和求得答案。

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const int mod=1e9+7;
ll s[MAXN];
ll a[4][MAXN];
int main()
{
    
    
    int n;
    cin>>n;
    a[1][0]=0;
    a[2][0]=0;
    for(int i=1;i<=n;i++)
    {
    
    
    	cin>>s[i];
    	a[1][i]=a[1][i-1];
    	a[2][i]=a[2][i-1];
    	if(i&1) a[1][i]+=s[i];
    	else a[2][i]+=s[i];
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
    
    
    	if(i&1)
    	{
    
    
    		ans=max(a[1][i]+a[2][n]-a[2][i],ans);
    	}
    	else
    	{
    
    
    		ans=max(ans,a[2][i]+a[1][n]-a[1][i]);
    	}
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_45755679/article/details/107294954