Codeforces Round #739 (Div. 3)A-F2

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #739 (Div. 3)A-F2相关的知识,希望对你有一定的参考价值。

A

直接暴力枚举即可

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

void solve()
{
	int n;
	cin>>n;
	for(int i=1;;i++)
	{
		if(i%10!=3 and i%3!=0) n--;
		if(n==0)
		{
			cout<<i<<'\\n';
			break;
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}

B

大意就是求一个数字对面的数字是多少?如果不存在,就输出-1

可以发现,两个相对的数字之差的绝对值的二倍就是一圈数字的个数,并且每两个相对数字之差绝对值都相等

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

void solve()
{
	int a,b,c;
	cin>>a>>b>>c;
	int n = abs(a-b);
	if(a>2*n or b>2*n or c>2*n) cout<<-1<<'\\n';
	else cout<<(c<=n ? c+n : c-n)<<'\\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}

C

题意:给一个数,让你输出题目中方框中对应的坐标

从左上角往右下角扩展的每个正方形中的数的个数为1,4,9,16…均为平方数

把一个数开方,当它是平方数时,输出对应的坐标
否则就是其它的情况,这个数减去小于它的平方数,对多出来的数进行判断即可

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

void solve()
{
	int n;
	cin>>n;
	int x = sqrt(n);
	if(n==x*x) cout<<x<<' '<<1<<'\\n';
	else 
	{
		if(n-x*x<=x) cout<<n-x*x<<' '<<x+1<<'\\n';
		else cout<<x+1<<' '<<2*x+1-(n-x*x)+1<<'\\n';
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}

D

题意:
可以把一个数进行两个操作:
1.删去任意一个数位上的数
2.在数的后面添加一个数
求把它变为2的次幂的最小操作次数

思路:
认真分析就是求2的次幂数和该数的最大匹配位数,或者2的次幂数的前缀在该数中的最长子序列的长度

枚举2的次幂数,灵活运用stl,把数字转化为字符串进行操作

因为2的次幂的前缀的必须每个数都出现,枚举n的每位,如果匹配到2的次幂数,p加一,接下来匹配下一位数

p为 能够匹配的位数,每次对结果进行更新,结果是2的次幂数的位数加上n的位数减去匹配位数的二倍

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

void solve()
{
	int n;
	cin>>n;
	string ss = to_string(n);
	ll res = inf;
	for(ll i=0;i<=60;i++)
	{
		string s = to_string(1ll<<i);
		int p = 0;//可以匹配的位数
		for(auto i :ss)
			if(i==s[p]) p++;
		res = min(res,(ll)s.size()+(ll)ss.size()-2*p);
	}
	cout<<res<<'\\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}
 

E

题意:
有一个s串,给次给s串删去一个同种类的字母,然后把剩下的串加到t串的后面,直到删去所有s串的字母。
给定最后的t串,求原来的s串是什么,以及删去s串字母的顺序

思路:
首先我们可以得出删除s串字母的顺序,因为有些字母肯定是先删除的,先删除的面就不会出现,后删除的后面可能还会出现。
我们从后面遍历t串,记录第一次出现的字母,倒序一下即为删除字母的顺序。比如hahahc,记录的就为cha,倒序一下,ahc就为删除的顺序

统计最终形成t串中每个字母出现的次数,可以根据删除字母的顺序算出初始的s串中各个字母的个数,从而就知道了初始串的长度len

长度知道了,我们可以得到一个初始的s串。
然后我们重新模拟题目中的过程,求一下最终的t串,与给的串进行比较一下就行

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

int cnt[26];
void solve()
{
	string res,s,t;
	for(auto &i:cnt) i=0;
	cin>>t;
	for(int i=t.size()-1;i>=0;i--)
	{
		cnt[t[i]-'a'] ++;
		if(cnt[t[i]-'a']==1) res+=t[i];
	}
	reverse(res.begin(),res.end());
	
	int len = 0;
	for(int i=0;i<res.size();i++)
		len += cnt[res[i]-'a']/(i+1);
	
	s = t.substr(0,len);
	
	string ss = s;
	for(int i=0;i<res.size();i++)
	{
		string temp;
		for(auto j : ss)
			if(j!=res[i])  temp += j; 
		ss = temp;
		s += temp;
	}
	if(t!=s) cout<<-1<<'\\n';
	else cout<<t.substr(0,len)<<" "<<res<<'\\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}
 

F1

F2

题意:
求一个大于等于x的最小的数,满足这个数的每个数位上的数的种类小于等于k

思路:
类似于贪心的思想

我们把这个数的各数位都加到集合中,如果集合的大小小于等于k说明满足条件,直接输出数n即可

对于其它的情况,依次把数n的前面的数加进集合中,当满足集合的大小大于k时,说明我们需要将这个数变大,当当前位为9时,如果加一那么前面的就会进位,那么前面的数的种类就会发生改变,所以往前找直到不为9时,把当前位加一,后面所有的位置为0。
当然这不一定满足题目的条件,所以需要继续进行下一次循环,直到我们得到的数的数位的种类小于等于k就返回答案

非常类似于数位DP的分析方法

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;


string solve()
{
	string n;
	int k;
	cin>>n>>k;
	while(1)
	{
		set<int> s;
		for(auto i:n) s.insert(i);
		if(s.size()<=k ) return n;
		
		s.clear();
		
		for(int i=0;i<n.size();i++)
		{
			s.insert(n[i]);
			if(s.size()>k)
			{
				while(n[i]=='9') i--;
				n[i] ++;
				for(int j=i+1;j<n.size();j++) n[j] = '0';
				break;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int _;
	cin>>_;
//	_ = 1;
	while(_--)
	{
		cout<<solve()<<'\\n';
	}
	return 0;
}
 

以上是关于Codeforces Round #739 (Div. 3)A-F2的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #739 (Div. 3) 题解

Codeforces Round #739 (Div. 3)A-F2

Codeforces Round #739 (Div. 3) ABCDEF1F2题解

Codeforces Round #739 (Div. 3) ABCDEF1F2题解

Codeforces Round #739 (Div. 3)(补题)

Codeforces Round #739 (Div. 3) F1. Nearest Beautiful Number (easy version)