Codeforces Round #786 (Div. 3) 题解 ABCD题

和团队可以ak cf div4的比赛了,cf div3的比赛做到4–5道题,很是可观了,希望继续努力,早日到达ak cf div3的水平。

A Number Transformation
题意:给你两个数x,y,问x能乘上a个b得到y吗?如果能,输出a和b,不能输出0 0。

分析:由于a和b范围很大,看y能否整除x,如果能,就乘以1个y/x,如果不能,就输出0 0。

题解:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int x, y;
		cin >> x >> y;
		if(y%x==0)
		{
			cout << 1 << " " << y/x << endl;
		}
		else
		cout << 0 << " " << 0 << endl;
	} 
	return 0;
}

SSRS_的代码很好看,看起来没有任何的多余,缩放也很漂亮,值得学习:

#include <bits/stdc++.h>
using namespace std;
int main(){
  int t;
  cin >> t;
  for (int i = 0; i < t; i++){
    int x, y;
    cin >> x >> y;
    if (y % x != 0){
      cout << 0 << ' ' << 0 << endl;
    } else {
      cout << 1 << ' ' << y / x << endl;
    }
  }
}

B Dictionary
题意:这个字典里的字都是两个小写英文字母组成的共有650个数,两字母不能重复,例如ab就是1,ac就是2,ba就是26……

分析:第一个字母的文章乘上权重加上第二个字母的位置即可,注意两字母的前后位置。

题解:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		char a,b;
		cin >> a >> b;	
		int cnt=0;
		cnt = (a-'a')*25;
		cnt += b-'a';
		if(b > a)
		{
			cnt-=1;
		}
		cout << cnt+1 << endl;
	}
 
	
	return 0;
}

这道题SSRS_使用了暴力枚举的方式,预处理把650种情况装进了vector中,我认为在速度上不如数学方法处理,但思路上应该比较容易。

#include <bits/stdc++.h>
using namespace std;
int main(){
  vector<string> S;
  for (int i = 0; i < 26; i++){
    for (int j = 0; j < 26; j++){
      if (i != j){
        string s;
        s += 'a' + i;
        s += 'a' + j;
        S.push_back(s);
      }
    }
  }
  int t;
  cin >> t;
  for (int i = 0; i < t; i++){
    string s;
    cin >> s;
    for (int j = 0; j < 650; j++){
      if (S[j] == s){
        cout << j + 1 << endl;
      }
    }
  }
}

C Infinite Replacement
题意:两个字符串s1和s2,第一个s1是由’a’组成的字符串,第二个s2是任意一个串。串中的’a’可以变成s2,问随意变化,一共存在多少种组合,无穷输出-1。

分析:这个考虑了三种情况,如果s2字符串中有’a’且长度大于1,就是无穷的变换;如果s2字符串只是一个’a’,就是一种情况;如果s2中没有’a’,变换数量就是2s1.length,最后记得开long long,不然多了两个wrong answer。

题解:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		string s1, s2;
		cin >> s1 >> s2;
		int c1=0,c2=0;
		for(int i=0;i<s1.length();i++)
		if(s1[i] == 'a')
		c1++;
		for(int i=0;i<s2.length();i++)
		if(s2[i] == 'a')
		c2++;
		
		if(c2>=1&&s2.length()>1)
		cout << "-1" << endl;
		
		if(c2==1&&s2.length()==1)
		cout << 1 << endl;
		
		long long ans = pow(2,c1);
		if(c2==0)
		printf("%lld\n", ans);
	
	} 
	return 0;
}

这个题SSRS_的思路是一样的,不过SSRS_的代码还是很不一样的简洁:

#include <bits/stdc++.h>
using namespace std;
int main(){
  int q;
  cin >> q;
  for (int i = 0; i < q; i++){
    string s, t;
    cin >> s >> t;
    int N = s.size();
    int M = t.size();
    int as = 0;
    for (int j = 0; j < N; j++){
      if (s[j] == 'a'){
        as++;
      }
    }
    int at = 0;
    for (int j = 0; j < M; j++){
      if (t[j] == 'a'){
        at++;
      }
    }
    if (at > 0){
      if (t == "a"){
        cout << 1 << endl;
      } else {
        cout << -1 << endl;
      }
    } else {
      cout << (((long long) 1) << as) << endl;
    }
  }
}

D A-B-C Sort
题意:三个数组a,b,c,往a数组中输入数据后进行两个操作。第一个操作,从a数组的后面取数放在b数组的中间,如果b数组中有奇数个数,可以选择中间数的前后插入。第二个操作,从b数组的中间取数,放在c数组后面,如果b数组是偶数,可以选择取哪一个。最后如果c可以变成不减的序列,输出YES,否则NO。

分析:经过分析找到了规律,由于有一个选择的操作,导致从a数组到c数组中两个相邻的数可以交换位置,只需要判断当前两个数的最小值大于前面两个数的最大值。

题解:

#include<bits/stdc++.h>
using namespace std;
int a[200010];
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
 
		for(int i=0;i<n;i++)
		cin >> a[i];
		
		if(n==1||n==2)
		{
			cout << "YES" << endl;
			continue;
		}
		
		bool f=1;
		if(n%2==0)
		{
			int maxx=max(a[0], a[1]);
			for(int i=3;i<n;i+=2)
			{
				if(maxx<=min(a[i], a[i-1]))
				{
					maxx = max(a[i], a[i-1]);
				}
				else
				{
					f = 0;
					break;
				}

			}
		}
		else
		{
			int maxx=a[0];
			for(int i=2;i<n;i+=2)
			{
				if(maxx<=min(a[i], a[i-1]))
				{
					maxx = max(a[i], a[i-1]);
				}
				else
				{
					f = 0;
					break;
				}

			}
		}
		if(f) cout << "YES" << endl;
		else cout << "NO" << endl;
	} 
	return 0;
}

看了SSRS_的代码,明白了对题目理解的很到位了。SSRS_也是,通过判断相邻两数解决了这道题。

#include <bits/stdc++.h>
using namespace std;
int main(){
  int t;
  cin >> t;
  for (int i = 0; i < t; i++){
    int n;
    cin >> n;
    vector<int> a(n);
    for (int j = 0; j < n; j++){
      cin >> a[j];
    }
    vector<int> b = a;
    sort(b.begin(), b.end());
    bool ok = true;
    if (n % 2 == 1){
      if (a[0] != b[0]){
        ok = false;
      }
    }
    for (int j = n % 2; j < n; j += 2){
      if (!(a[j] == b[j] && a[j + 1] == b[j + 1] || a[j] == b[j + 1] && a[j + 1] == b[j])){
        ok = false;
      }
    }
    if (ok){
      cout << "YES" << endl;
    } else {
      cout << "NO" << endl;
    }
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三元湖有大锦鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值