A.Dislike of Threes
AC代码:
#include
#include
#include
using namespace std;
const int N=2e5+10;
int f[N];
int cnt;
int main()
{
for(int i=1;;i++){
if(i%3!=0&&i%10!=3) f[++cnt]=i;
if(cnt>=1000) break;
}
int t;
cin>>t;
while(t--){
int k;
cin>>k;
cout<
B.Who's Opposite?
AC代码:
#include
#include
#include
using namespace std;
void solve()
{
int a,b,c;
cin>>a>>b>>c;
if(a>b) swap(a,b);
int sum=2+(b-a-1)*2;
if(c>sum){
cout<<-1<sum||b>sum){
cout<<-1<sum){
cout<<-1<>t;
while(t--)
solve();
return 0;
}
C.Infinity Table
每一行的第一个都是2的次幂,通过二分来找到是哪一行
注意二分的范围,如果开太大,平方超出int范围,会变成负数,导致错误
AC代码:
#include
#include
#include
using namespace std;
int sqr(int x){
return x*x;
}
void solve()
{
int k;
cin>>k;
int l=1,r=4e4;
while(l=k) r=mid;
else l=mid+1;
}
int x,y;
int diff=sqr(l)-k;
if(diff<=l-1) {
x=l;
y=diff+1;
}
else{
x=l-(diff-(l-1));
y=l;
}
cout<>t;
while(t--)
solve();
return 0;
}
D.Make a Power of Two
先打表,预处理2的次幂,以字符串的形式存储,存储尽可能多的2的次幂(因为还有前导0)
数字n也以字符串的形式输入进来,记为字符串ss,然后将字符串与打好表的所有2的次幂进行比较,
利用双指针,必须从左往右按顺序依次匹配,也就是说对于每一个2的次幂字符串,如果前一位没有被匹配,那么就不去匹配后一位,因为只能在最右边加数,前一位没有匹配到,我们是不能通过删除和在右边添加元素来使得这个数出现的
然后如果某一个2的次幂每一位都被匹配的话,就只要删除多余的位数
否则,除了要删除多余的位数,还要在右边添加没有匹配到的位数
用res记录答案,对于变成每一个2次幂所需的操作次数,都取最小
AC代码:
#include
#include
#include
#define int long long
using namespace std;
const int N=110;
string s[N];
//打表
void init()
{
for(int i=0;i<61;i++){
int x=1ll<>ss;
int res=2e9;
for(int i=0;i<61;i++){
int match=0;
int p=0,q=0;
while(ss[q]){
if(ss[q]==s[i][p]){
p++;
match++;
}
q++;
}
int len1=s[i].size(),len2=ss.size();
if(match==len1) res=min(res,len2-match);
else res=min(res,len2-match+len1-match);
}
cout<>t;
while(t--)
solve();
return 0;
}
或者在双指针匹配的同时,如果不匹配就执行删除操作(即操作数+1),然后最后s[i]中没有匹配的都加到ss的右边
AC代码:
#include
#include
#include
#define int long long
using namespace std;
const int N=110;
string s[N];
void init()
{
for(int i=0;i<61;i++){
int x=1ll<>ss;
int res=2e9;
for(int i=0;i<61;i++){
int cnt=0;
int match=0;
int p=0,q=0;
while(ss[p]){
if(ss[p]==s[i][q]){
q++;
match++;
}
else cnt++;
p++;
}
int len1=ss.size(),len2=s[i].size();
res=min(res,cnt+len2-match);
}
cout<>t;
while(t--)
solve();
return 0;
}
E.Polycarp and String Transformation
先根据变换后的字符串t得到删除的字符及其顺序,因为字符越是在后面则越晚被删除
然后因为原字符串s第一次加到了字符串t中,所以只需确定其长度即可通过遍历得到
原字符串s的长度为字符串t中第一次删除的字符个数+第二次删除的字符个数除以2+...
然后遍历得到字符串s
最后验证字符串s按题目操作之后得到的字符串是否和t相等,如果相等则正确,否则输出-1
注意,vector.erase()中要写迭代器,即地址,不能写值
for(auto v:s) 得到的v是值,不能直接erase(值)
可以用vector删除所有与指定值相等的元素
AC代码:
#include
#include
#include
#include
#include
F1.F2.
Nearest Beautiful Number (easy version)
Nearest Beautiful Number (hard version)
参考zhbbbb!
判断当前n不同数字个数是不是小于等于k,如果小于等于k,则直接输出
找到第一个大于k的不同数,这是关键,每次都是找第一个大于k的不同数
使得这位数+1,后面全置为0,原因是该位已经是第k+1位不同的数了,并且我们要找的数需要大于等于n,所以只能将其变大,但又不能一下子变太大,因为要找最小的大于等于n的,故加1,然后再判断当前n不同数字的个数是否小于等于k,如此反复
注意,如果找到的第k+1个不同的数是9,则需要进位,那么只需要往前移动,直到找到不是9的位,对其+1,然后后面全部置为0
AC代码:
#include
#include
#include
#include
#include