【Codeforces #762 (Div. 3)】B—E

B - Squares and Cubes

题解:
n有1e9,但是根号n只有1e4,这样就可以直接做了,验证1-根号n

#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
#define ll long long
const int maxn=1e5+7;
//int a[maxn],vis[100];
int main() {
	int t;cin>>t;
	ll x;
	while(t--){
		cin>>x;
		ll now=sqrt(x);
		ll sum=0;
		set<ll>st;
		for(ll i=2;i<=now;i++){
		    st.insert(i*i);
			if(i*i*i<=x)st.insert(i*i*i);
		}
		cout<<st.size()+1<<endl;
	}
	return 0;
}

C. Wrong Addition

题意:
特殊的计算,规则是:
两个数的每个位置相加(不等前面补零)得到的数相连接在一起。
题解:
直接模拟去做。
(字母代替,假设a(+)b=c,a、c给出)
a、c从后往前对照记录。
如果c的某位置大于a,直接记录该位置的c-b
如果小于,则它必须由两个单个的字符加来且位于10-19之间。那么a的上一个必须为1,否则必定组合不成。如若成立,记录10+c该位置的数-a该位置数。

#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
const int maxn=1e4+7;
//int a[maxn],vis[100];
int main() {
	int t;cin>>t;
	while(t--){
		string s1,s2;cin>>s1>>s2;
		int i=s1.size()-1,j=s2.size()-1;
		int f=1,now=0;
		char s3[20];
		while(j>=0){
			int sum=s2[j]-'0';
			int a=i<0?0:s1[i]-'0';
			
			if(a>sum){
				j--;
				if(j<0){
				f=0;break;
			    }
				if(s2[j]-'0'==1)s3[now++]=(char)(10+s2[j+1]-a);
				else {
				f=0;break;
			    }
			}
			else s3[now++]=(char)(sum-a+'0');
			i--;
			j--;
		}
		if(i>=0)f=0;
		if(f){
			int n0=0;
			for(int i=now-1;i>=0;i--){
				if(s3[i]!='0')n0++;
				if(n0>0)
				pr("%c",s3[i]);
			}
			pr("\n");
		}
		else pr("-1\n");	
	}
	return 0;
}

D. The Winter Hike

题意:
m个商店,n个朋友
要求小于(n-1)个商店能买礼物的期待值最小值的最大化
p数组为i商店买给j朋友的期待值

题解:
二分模拟答案
check为真需要:1》保证每个朋友都有礼物。2》至少有一个商店买的礼物大于等于2

#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
const int maxn=1e5+7;
//int a[maxn],vis[100];
vector<int>p[maxn];
int n,m;
bool check(int mid){
	set<int>st;
	bool f=0;
	int cnt=0;
	for(int i=0;i<m;i++){
		cnt=0;
		for(int j=0;j<n;j++)
		if(p[i][j]>=mid){st.insert(j),cnt++;}
			if(cnt>1)f=1;
	}

	if(st.size()==n&&f)return 1;
	else return 0;
}
int main() {
	int t;cin>>t;
	int x;
	while(t--){
		cin>>m>>n;
		for(int i=0;i<m;i++){
		    p[i].clear();
			for(int j=0;j<n;j++) {
				cin>>x;p[i].push_back(x);
			}
		}
		//二分
		int l=1,r=1e9;
		int ans=r;
		while(l<=r){
			int mid=(l+r)/2;
			if(check(mid)){
			    ans=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		cout<<ans<<endl;	
	}
	return 0;
}

E - MEX and Increments

题意:要求输出0-n的每一个为MEX的操作数

题解:sort函数从小到大排号
两种情况:
ans=sum+该位置的个数。
该位置个数大于等于1,留下一个该位置,剩下都放入优先队列q中。
该位置个数为0,sum=sum+(i-q.top()),如果此时取不出,则所有大于i的不成立,-1.

注意一些地方得开ll

#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pr printf
#define ll long long
const int maxn=2e5+7;
//int a[1200][6];
ll ans[maxn],a[maxn];
int main()
{
    int t;int n;
    sc("%d",&t);
    while(t--){
    	    int n;cin>>n;
    	    map<ll,ll>mp;
    	    for(int i=1;i<=n;i++)ans[i]=-1;
    	    for(int i=1;i<=n;i++){
    	    	cin>>a[i];
    	    	mp[a[i]]++;
			}
			ll sum=0;
			sort(a+1,a+n+1);
    	    priority_queue<ll>q;
    	    for(int i=0;i<=n;i++){
    	    	ans[i]=sum+mp[i];
    	    	if(mp[i]){
    	    		while(mp[i]-->1){
    	    			q.push(i);
    	    			//mp[i]--;
				    }
				}
				else {
					if(q.size()==0)break;
					sum+=i-q.top();
					q.pop();
				}
			}
			for(int i=0;i<=n;i++)cout<<ans[i]<<" ";
			cout<<endl;
    }
    return 0;
}        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值