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)