目录
2. Divisible by Twenty-Five(模拟,构造)
10.Anonymity Is Important(STL,模拟)
1.Different Differences(贪心)
链接:Problem - 1772C - Codeforces
题意:
解题思路:最大化相邻两个数之间的差值,从n开始减差值ax-ay=1,2,3.... (注意到最后如果不能让差值一直增加(因为要构造的数是1~n),如果不能增加了就固定为1)
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;cin>>t;
while(t--)
{
int k,n;cin>>k>>n;
int tmp=0,a[n];
for(int i=1;i<=k;i++)
{
if(n-tmp>k-i)
{
n=n-tmp;
a[i]=n;
}
else
{
a[i]=a[i-1]-1;
}
tmp++;
}
for(int i=k;i>=1;i--)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
return 0;
}
2. Divisible by Twenty-Five(模拟,构造)
链接:Problem - 1575D - Codeforces
题意:
解题思路:被25能整除的数末两位是25的倍数。00,25,50,75,根据最后两位数的情况构造
代码:
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
ll fast(ll x, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * x;
x = x * x;
n >>= 1;
}
return res;
}
//25 50 75 00
ll solve(string s) {
if (s[0] == '0') return 0;
ll len = s.size();
ll xia = 0, X = 0;
for (ll i = 1; i < len - 2; ++i)
{
if (s[i] == '_') xia++;
if (s[i] == 'X') X++;
}
int tmp = 0;
if (s[len - 2] == '_')
{
if (s[len - 1] == '_') tmp = fast(10, xia) * 4;
else if (s[len - 1] == 'X') {
if (s[0] == 'X') return fast(10, xia) * 2 * (s[0] == '_' ? 9 : 1);
else return fast(10, xia) * 4 * (s[0] == '_' ? 9 : 1);
} else if (s[len - 1] == '0' || s[len - 1] == '5') tmp = fast(10, xia) * 2;
else tmp = 0;
}
else if (s[len - 2] == 'X')
{
if (s[0] == 'X') {
if (s[len - 1] == 'X') return 0;
else if (s[len - 1] == '_') return fast(10, xia) * 3 * (s[0] == '_' ? 9 : 1);
else if (s[len - 1] == '0') return fast(10, xia) * (s[0] == '_' ? 9 : 1);
else if (s[len - 1] == '5') return fast(10, xia) * 2 * (s[0] == '_' ? 9 : 1);
return 0;
} else {
if (s[len - 1] == '0' || s[len - 1] == '5') tmp = fast(10, xia) * 2;
else if (s[len - 1] == '_') tmp = fast(10, xia) * 4;
else if (s[len - 1] == 'X') tmp = fast(10, xia);
else tmp = 0;
}
}
else if (s[len - 2] == '0' || s[len - 2] == '2' || s[len - 2] == '5' || s[len - 2] == '7')
{
if (s[len - 2] == '0' || s[len - 2] == '5')
{
if (s[len - 1] == '0') tmp = fast(10, xia);
else if (s[len - 1] == 'X')
{
if (s[0] == 'X') return 0;
else
{
tmp = fast(10, xia);
}
}
else if(s[len - 1]=='_')
{
tmp = fast(10, xia);
}
}
else
{
if (s[len - 1] == '5') tmp = fast(10, xia);
else if (s[len - 1] == 'X')
{
if (s[0] == 'X') return fast(10, xia) * (s[0] == '_' ? 9 : 1);
else {
tmp = fast(10, xia);
}
}
}
} else tmp = 0;
if (s[len - 1] != 'X' && s[len - 2] != 'X' && X != 0 && s[0] != 'X') tmp = tmp * 10;
if (s[0] == '_' || s[0] == 'X') tmp = tmp * 9;
return tmp;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
string s;
cin >> s;
if (s.size() == 1) {
if (s[0] == '0' || s[0] == '_' || s[0] == 'X') cout << 1;
else cout << 0;
return 0;
}
if (s.size() == 2) {
if (s[0] == '0') cout << 0;
else if (s[0] == '_') {
if (s[1] == '_') cout << 3;
else if (s[1] == 'X') cout << 3;
else if (s[1] == '0') cout << 1;
else if (s[1] == '5') cout << 2;
else cout << 0;
} else if (s[0] == 'X') {
if (s[1] == '_') cout << 3;
else if (s[1] == 'X') cout << 0;
else if (s[1] == '0') cout << 1;
else if (s[1] == '5') cout << 2;
else cout << 0;
} else if (s[0] == '2' || s[0] == '7') {
if (s[1] == 'X' || s[1] == '_' || s[1] == '5') cout << 1;
else cout << 0;
} else if (s[0] == '5') {
if (s[1] == 'X' || s[1] == '_' || s[1] == '0') cout << 1;
else cout << 0;
} else cout << 0;
return 0;
}
ll res = solve(s);
cout << res;
return 0;
}
3.Arrays Sum(思维)
链接:Problem - 1408B - Codeforces
题意:
每一个b数组不同元素不超过k
解题思路:
因为他是单调递增数组,找到一共有多少不同元素sum,第一个b数组先包含前k个不同元素,其他的等于第k个元素如k=3【1,2,3,3,3...]
之后的b数组每个都可以解决k-1个元素,前面解决了的元素用0占位(所以只能解决k-1个)。
【既sum里面先减去k,剩下的sum里还包含多少(k-1)?】
特殊情况k==1,必须整个a数组元素相同否则输出-1
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n;cin>>n;
double k;cin>>k;
double a[110],sum[110]={0};
for(int i=1;i<=n;i++)
{ sum[i]=sum[i-1];
cin>>a[i];
if(i==1)sum[i]=1;
else if(a[i]!=a[i-1])
sum[i]=sum[i-1]+1;
}
if(k==1)
{
if(sum[n]!=1)cout<<-1<<endl;
else cout<<1<<endl;
}
else
{
if(k>=sum[n])cout<<1<<endl;//4 4 1,1,1,1
else
cout<<ceil((sum[n]-k)/(k-1))+1<<endl;//注意上取整 样例: 4 3 1,4,5,7
}
}
return 0;
}
4. Power Sequence(注意范围)
链接:Problem - 1397B - Codeforces
题意:
思路:c直接从1开始枚举,算到最小成本后成本肯定会增大就可以break
注意当数达到1e18后就不能继续乘了

代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+100;
ll a[N];
ll fast(ll x, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * x;
x = x * x;
n >>= 1;
}
return res;
}
ll n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
ll c=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
ll ans=1e18;
ll res=0;
for(ll i=1;;i++)
{ res=0;ll tt=1;
for(int j=0;j<n;j++)
{
res+=abs(a[j]-tt);
tt*=i;
if(tt*i>=1e18)
{
break;//防止溢出
}
}
if(res<ans)ans=res;
else break;
}
cout<<ans;
return 0;
}
5.Game of Ball Passing(思维,贪心)
链接:Problem - 1649B - Codeforces
题意:
思路:如果要传球最多次数的人小于剩下的人传球次数总和,那一定能用一个球传完,(每次都由最多的人传给其他人,其他人再传回来,直到把最多的人消耗完,又由下一个最多的重复以上步骤,一定能用一个球满足所有人的次数)
如果大于,传完剩下所有人后还有球在他手中,这时假设把他球传到空地,这就是球的个数。
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+9;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;cin>>t;
while(t--)
{
int n;
cin>>n;
ll sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];sum+=a[i];
}
sort(a+1,a+1+n);
if(a[n]==0)
{
cout<<0<<endl;
continue;
}
else if(a[n]<=sum-a[n])
cout<<1<<endl;
else
{
ll res=a[n]-(sum-a[n]);
cout<<res<<endl;
}
}
return 0;
}
6.MEX and Array(贡献法)
链接:Problem - 1637B - Codeforces
题意:
思路:元素0 在每一个分段里面贡献值为2(1是长度c,另一个1是mex:除了0之外的最小是1)
非零元素在每一个分段里面贡献为1 (1长度c)
找出每个元素在多少个分段(子数组)里:它前面的长度(包括它本身)*他后面的长度(包括它本身)
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;cin>>t;
while(t--)
{ll ans=0;
int n;cin>>n;
for(int i=1;i<=n;i++)
{
int a;cin>>a;
if(a==0)
{
ans+=2*(i)*(n+1-i);
}
else
{
ans+=(i)*(n+1-i);
}
}
cout<<ans<<endl;
}
return 0;
}
7.Doremy's Paint(思维)
链接:Problem - 1764A - Codeforces
题意:
思路:把r-l-c(l,r)展开理解,就是(r~l中的元素个数)-(r~l中的不同元素的个数),剩下的数就是r~l中每种相同元素的个数-1;
所以要最大化肯定要把含有相同元素的段全部包含进去,直接就是1~n
代码:
#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N=1e5+9;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;cin>>t;
while(t--)
{
int n;cin>>n;
for(int i=1;i<=n;i++)
{int x;
cin>>x;
}
cout<<1<<" "<<n<<endl;
}
return 0;
}
8.Breaking the Wall(模拟,思维)
链接:Problem - 1674E - Codeforces
题意:
思路:只有3种情况:
1.两个相邻的,2.三个中两边的(先打中间),3.最小的两个墙距离大于3(两个分开打)
3:分开打,每一个次数对答案的贡献都是2,墙小于2后对答案贡献1
2:先打中间的(对答案贡献2)直到其中一个=0,然后打另一个(对答案贡献2或1)
1:如果相邻两个中max>=2*min那直接打max向上取整
如果max<2*min:打(max+min)时每一次对答案贡献3(也要上取整)
代码:
#include<bits/stdc++.h>
typedef long long ll;
const int N=2e5+9;
int a[N],b[N];
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
int r1=b[1],r2=b[2];
int ans1=0,ans2=1e9,ans3=1e9;
ans1=r1/2+r1%2+r2/2+r2%2;
for(int i=1;i<n;i++)//相邻的
{
int x=a[i],y=a[i+1],tmp=0;
int mi=min(x,y);
int ma=max(x,y);
if(ma>=mi*2) tmp=(ma+1)/2;
else tmp=(ma+mi+2)/3;
if(tmp<ans2)ans2=tmp;
}
for(int i=1;i<n-1;i++)
{
int x=min(a[i],a[i+2]);
int y=max(a[i],a[i+2]);
// cout<<x<<endl<<y;
int tmp=x+(y-x)/2+(y-x)%2;
if(tmp<ans3)ans3=tmp;
}
//cout<<"ans1:"<<ans1<<"ans2:"<<ans2<<" "<<ans3<<endl;
int res=min(ans1,min(ans2,ans3));
cout<<res;
return 0;
}
9.Remove Adjacent(贪心)
链接:Problem - 1321C - Codeforces
题意:
也就是只要左,右有它前一个字母就可以把它自己删掉
思路:大的字母先删肯定是最优的,因为它不可能让别人被删掉,只能自己被删
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int s;cin>>s;
string a;cin>>a;
int ans=0;
for(char i='z';i>='a';i--)//优先去掉大的更好,因为大的不能作为删别人的依据
{
for(int j=0;j<a.size();j++)
{
if(a[j]==i&&(j>0&&a[j-1]==i-1||j<a.size()-1&&a[j+1]==i-1))
{
a.erase(j,1);j=-1;//每一次都从新找,直到这个大的没有了,就不会进入这个if ,就会找下一个大的字母
ans++;
}
}
}
cout<<ans;
return 0;
}
10.Anonymity Is Important(STL,模拟)
链接:Problem - 1641C - Codeforces
题意:

思路: 可以用set代表不确定的人,初始化都是不确定则将所有人插入st.将不是病人的从set里删除。对于至少有一个病人的区间尽可能缩小到只有一个人的区间,用map[l]=r存,将会包含别的区间的大区间不插入,或删掉,(因为st存的是不确定的人所以大区间中表示至少有一人也是不确定,则可以用小区间代替)。
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
map<int,int>mp;
set<int>st;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;cin>>n>>q;
for(int i=0;i<=n+1;i++)st.insert(i);
while(q--)
{
int t;cin>>t;
if(t)
{
int j;cin>>j;
if(!st.count(j))
cout<<"NO"<<endl;
else
{
int l=*prev(st.find(j));
int r=*next(st.find(j));
auto it=mp.upper_bound(l);
if(it!=mp.end()&&it->first<=j&&it->second<r)cout<<"YES"<<endl;
else cout<<"N/A"<<endl;
}
}
else
{
int l,r,x;
cin>>l>>r>>x;
if(x==0)
{
while(1)
{
auto it=st.lower_bound(l);
if(*it>r)break;
st.erase(it);
}
}
else
{
auto it=mp.lower_bound(l);
if(it!=mp.end()&&it->second<=r)continue;
mp[l]=r;
it=mp.find(l);//找前面有没有包含他
while(it!=mp.begin()&&r<=prev(it)->second)mp.erase(prev(it));
}
}
}
return 0;
}

3494

被折叠的 条评论
为什么被折叠?



