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;
}