Codeforces题目练习

1.Codeforces Round #752 (Div. 2)

Dashboard - Codeforces Round #752 (Div. 2) - Codeforces

A.Era

题意背景:对于给定当前整数序列,要求在可以向内部添加任意数的情况下,使最终数列满足ai<=i即可,每次添加后,要求在已改变数列基础上进行改变。

自解:

遍历整个整数序列,若出现元素大于当前所处位置情况,即ai>i,那么令ai=i,当前位置向后所有元素依次减少ai-i个大小。

#include<iostream>
#include<cstring>
using namespace std;
long long a[105];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		memset(a,0,sizeof(a));
		int n;
		cin>>n;
		long long sum=0;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++)
		{
			if(a[i]>i)
			{
				sum+=(a[i]-i);	
				
			long long temp=a[i]-i;
			for(int j=i;j<=n;j++)
			{
				a[j]-=temp;
			}
			}
		}
		cout<<sum<<endl;	
	}	
} 

官解:

无需每一项都改变,只要找到元素与对应位置差值最大即可,然后在最前面添加元素,当差值最大情况满足时,剩余所有情况全部满足。

#include<bits/stdc++.h>
using namespace std;
 
int main() {
  int t; cin >> t;
  while (t--) {
    int n; cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
      int k; cin >> k;
      ans = max(ans, k - i);
    }
    cout << ans << '\n';
  }
  return 0;
}

B.XOR Specia-LIS-t

题意背景:给定一个整数序列,可以将其分割成一个或多个连续子序列,要求序列中每个元素只属于一个序列,对于每个子序列,可通过删除零个或全部的情况下生成最长递增子序列,要求每个序列对应的最长递增子序列长度按位异或等于0,判断这一可能性。

自解:

首先判断奇偶性,若为偶数,则每个元素都单独划分,最终可以得到偶数个1互相异或,最终结果一定为0。(偶数个数互相异或,无论异或任意值都为0)

若为奇数,则可判断是否存在连续两项递建或相等,此时可令其余所有元素单独划分,该两项一同划分,最终仍能得到偶数个1相互异或,最终结果同样为0,反之相反。

#include<iostream>
#include<algorithm>
using namespace std;
long long a[200005];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
		}
		int ok=1;
		if(n&1)
		{
			long long maxn=a[0];
			for(int i=1;i<n;i++)
			{
				if(maxn>=a[i])
				{
					cout<<"YES"<<endl;
					ok=0;
					break;
				}
				maxn=max(maxn,a[i]);
			}
			if(ok) cout<<"NO"<<endl;
		}
		else cout<<"YES"<<endl;
	}
}

官解:

若整数序列个数为奇数且无后项小于等于前项,则为不可能情况,反之可能。

#include<bits/stdc++.h>
using namespace std;
 
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int t; cin >> t;
  while (t--) {
    int n; cin >> n;
    vector<int> a(n + 1);
    bool inc = true;
    for (int i = 1; i <= n; i++) {
      cin >> a[i];
      inc &= a[i] > a[i - 1];
    }
    if (n % 2 == 0 or !inc) {
      cout << "YES\n";
    }
    else {
      cout << "NO\n";
    }
  }
  return 0;
}

C. Di-visible Confusion

题意背景:

给定整数序列,若当前对应位置元素ai不可以被(i+1)整除,则删掉,否则保留,每一次删除要在上一次操作基础上重新计算,试判断是否可以按此方法删除整个数列。

自解:

首先我们发现,整数序列数据大小满足1≤ai≤10^9,然后我们计算一下可知,14!=87,178,291,200>ai,则对于一个数据,我们最多判断14次该数是否可以整除当前位置+1及向前推进位置+1,期间若出现成立即可,若全不可,则直接判定不可能。

#include<iostream>
using namespace std;
long long a[100005];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		int ok=1;
		for(int i=1;i<=n;i++)
		{
			int yes=0;
			for(int j=i+1,k=1;j>=2&&k<=14;j--,k++)
			{
				if(a[i]%j)
				{
					yes=1;
					break;
				}
			}
			ok&=yes;
			if(!ok) break;
		}
		cout<<(ok?"YES":"NO")<<endl;
	}
}

官解:与上大体相同。

D. Moderate Modular Mode

题意背景:给出两个整数x,y,试着找出一个整数n满足n mod x=y mod n,可以确定这样的n一定存在,若有多个n,可输出任意一个n即可。

自解:

考虑当x>y的情况下,即令n=x+y,此时满足x+y mod x=y=y mod x+y

若相等,即令n=x即可

对于x<y的情况,未想出正确解答方案。

官解:
对于x<y的情况,我们进行如下考虑:

1)n不可以小于x

假设n<x,则n mod x=n,y mod n<n,此时等式不成立;

2)n不可以大于y

假设n>y,则n mod x<x,y mod n=y,此时等式不成立;

由以上可知,n一定是在x~y之间的一个数,接下来我们考虑这个数具体应该是多少:

我们在一条线段上确定零点,x和y对应的位置,我们假定从零点出发,每一次走x个单位长度,则我们在走过k次后,距离y将出现小于x个的单位长度,此时我们分两步走到y,我们假定现在的出发点是p,则p=y-y mod x,同时p mod x=0,我们选取p~y中间一半距离为p1,此时p2=p+p1,会发现一点

p2 mod x=p1,而y mod p2=p1,即满足等式,n=p2,此题结束。 

#include<algorithm>
using namespace std;
int main()
{
	long long t;
	cin>>t;
	while(t--)
	{
		long long a,b;
		cin>>a>>b;
		unsigned long long ans=0;
		if(a>b) ans=a+b;
		else ans=b-b%a/2;
		cout<<ans<<endl;
	}
}

2.Codeforces Round #753 (Div. 3)

Dashboard - Codeforces Round #753 (Div. 3) - Codeforces

A. Linear Keyboard

题意背景:

给定26位小写英文字母排列顺序,接下来给出一串不规则小写英文字母字符串,计算写下当前字母耗费时间(即字母对应顺序位置)总和,写下当前字母后,下一次书写需在当前位置继续执行。

自解:

将每个字母与对应位置数字使用map相联系,计算相邻两个字母位置数字差的绝对值之和。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		map<char,int>m;
		m.clear();
		string s,v;
		cin>>s>>v;
		int x=s.size(),y=v.size();
		int sum=0;
		for(int i=0;i<x;i++)
		{
			m[s[i]]=i;
		}
		for(int i=1;i<y;i++)
		{
			sum+=abs(m[v[i]]-m[v[i-1]]);
		}
		cout<<sum<<endl;
	}
	return 0;	
} 

官解:

使用index函数,该函数目的返回查找对象的索引位置,若不存在则抛出异常。

例:list.index(obj)

t = int(input())
for _ in range(t):
    k, s = input(), input()
    res = 0
    for i in range(1, len(s)):
        res += abs(k.index(s[i]) - k.index(s[i - 1]))
    print(res)

B.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值