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

嘿嘿嘿



A. Dislike of Threes

题目链接
十进制中去掉能被三整除或个位数是三的数,问第 k k k个是谁

开始一直在推算式然后发现 k k k的范围刚好是1000然后样例也给了第1000个数是1666就直接暴力枚举

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10005;
int a[N];
signed main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	while(t--) {
        int n;
        cin>>n;
        int ans=0;
        for(int i=1; i<=1666; i++) {
            if(i%10==3||i%3==0) continue;
            else ans++;
            if(ans==n) {
                cout<<i<<endl;
                break;
            }
        }
	}
	return 0;
}

B. Who’s Opposite?

题目链接
题意就是问你一个环上有偶数个数字 1 − ? 1-? 1?,给你 a , b a, b a,b是相对的问你 c c c对面的是哪个数字,不合法就输出 − 1 -1 1

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10005;
signed main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	while(t--) {
        int a, b, c;
        cin>>a>>b>>c;
        int m=max(a, b);
		int n=abs(a-b);//n+n就是点数
		if(n+n<m ||n+n<c) {//判这个环对不对
			cout<<"-1"<<endl;
			continue;
		}
        int ans=0;
        if(c-n>=1) ans=c-n;//与c对面的就是c-n或c+n
        else if(n+n>=c+n) ans=c+n;
        else ans=-1;
        cout<<ans<<endl;
	}
	return 0;
}

C. Infinity Table

题目链接
题意如图

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10005;
int a[N];
signed main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	while(t--) {
        int n;
        cin>>n;
        int m = sqrt(n) + 1;
        n=n-(m-1)*(m-1);
		if(n==0) cout<<m-1<<" "<<1<<endl;
        else if(n==m) cout<<m<<" "<<m<<endl;
		else if(n<m) cout<<n<<" "<<m<<endl;
		else cout<<m<<" "<<2*m-n<<endl;
	}
	return 0;
}

D. Make a Power of Two

题目链接
给你个数,你能去掉一个数,或者在最后加上个数,使这个数变成 2 2 2的幂次,问最少操作次数

一开始忘记只能在最后加数字直接找最长公共子序列。。
所以只要暴力枚举所有2幂次数,因为你只能擦去和在最后添加数字不能在前面加,所以要保证这个幂次数的某个前缀的所有数字你都包含然后计算答案 = = =擦去的 + + +加在最后的

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 105;
string ss[N];
string f(int n) {
    string ans="";
    while(n) {
        ans=char(n%10+'0')+ans;
        n/=10;
    }
    return ans;
}
int ans;
signed main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	for(int i=0; i<=60; i++) {//1e9不够呜呜呜
        int m=pow(2, i);
        ss[i]=f(m);
	}
	while(t--) {
        string s;
        cin>>s;
        ans=1e9;
        for(int k=0; k<=60; k++) {
            int n=s.size(), m=ss[k].size();
            int cnt=0;
            for(int i=0, j=0; i<m&&j<n;) {
                    if(s[j]==ss[k][i]) {
                        j++;
                        i++;
                        cnt++;
                    }else j++;
            }
            ans=min(ans, n-cnt+m-cnt);
        }
        cout<<ans<<endl;
	}
	return 0;
}

E. Polycarp and String Transformation

题目链接
还没补 好像说很水

F1. Nearest Beautiful Number (easy version)

题目链接
问你大于等于 n n n的数里包含不同数的个数不超过 k k k个的最小数是谁 ( 1 < = k < = 2 ) (1<=k<=2) (1<=k<=2)

div3应该没数位dp吧ahh
主要是不熟qwq
就又看错题了以为是 k k k种 wa3发
直接暴力枚举只有一个和只有两个不同数的所有数存起来然后二分查找

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 105;
int a[15][15];
set<int> sss, se;
signed main() {
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int cnt=0;
    for(int i=1; i<=9; i++) {
        for(int j=1; j<=10; j++) {
            a[j][i]=a[j-1][i]*10+i;
            sss.insert(a[j][i]);
        }
    }
    int cnt1=0;
    for(int q=0; q<=9; q++) {//枚举第一个数 可以是0
        for(int h=0; h<=9; h++) {//第二个数
            if(q==h) continue;
            for(int k=2; k<=10; k++) {
                for(int i=1; i<(1<<k)-1; i++) {//二进制枚举
                    int x=0;
                    int m=1;
                    bool flag=1;
                    for(int j=0; j<k; j++) {
                        if(i&(1<<j)) x=x*10+q;
                        else x=x*10+h;
                    }
                    if(flag)se.insert(x);
                }
            }
        }
    }
    for(int i=0; i<=9; i++) se.erase(i);//因为se存的是只两个不同数 额虽然好像也不需要了因为是不超过k
    int t;
    cin>>t;
	while(t--) {
        int k, n;
        cin>>n>>k;
        if(k==1) {
            set<int>::iterator it = sss.lower_bound(n);
            cout<<*it<<endl;
        }else {
            set<int>::iterator itt = sss.lower_bound(n);
            set<int>::iterator it = se.lower_bound(n);
            cout<<min(*itt, *it)<<endl;
        }
	}
	return 0;
}

F2. Nearest Beautiful Number (hard version)

题目链接
(k<=10)
6b9a6049f0b100e154731a791f.png)

数位dp好
另法:dpgg说可以拿出现的前k-1个不同的数,肯定是对的,高位变很亏,然后我们枚举最后一个数是什么就好了

#include <bits/stdc++.h>
#define int long long
using namespace std;
string n;
int k;
set<int> se;
int dfs(int pos, int val, bool flag) {
	if(!n[pos]) return val;
	int now=n[pos]-'0';
	for(int i=flag?0 : now; i<=9; i++) {
		if(se.count(i)) {
			int res=dfs(pos+1, val*10+i, flag||i>now);
			if(res!=-1) return res;
		}else if(se.size()<k) {
			se.insert(i);
			int res=dfs(pos+1, val*10+i, flag||i>now);
			if(res!=-1) return res;
			se.erase(i);
		}
	}
	return -1;
}
signed main() {
	int t;
	cin>>t;
    while(t--) {
		cin>>n>>k;
		se.clear();
		cout<<dfs(0, 0, 0)<<endl;
    }
    return 0;
}

总结

好久没骗访客了ahhh

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值