A.签到题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int a,b,c;
cin>>a>>b>>c;
a=a-b;
a=min(a,c);
// cout<<a<<endl;
c=c-a;
cout<<c<<endl;
return 0;
}
B.签到题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int check( int x){
int cnt=0;
while(x){
cnt++;
x/=10;
}
if(cnt%2==1) return 1;
return 0;
}
int main(){
int n;
cin>>n;
int ans=0;
for( int i=1;i<=n;i++){
if(check(i)) ans++;
}
cout<<ans<<endl;
return 0;
}
C.贪心算法
只要该位置能减一,就减一
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int w[100100];
int main(){
int n;
cin>>n;
for( int i=1;i<=n;i++){
scanf("%d",&w[i]);
}
for( int i=1;i<=n;i++){
if(w[i]>w[i-1]) w[i]--;
else if(w[i]==w[i-1]){
continue;
}
else {
cout<<"No"<<endl;
return 0;
}
}
cout<<"Yes"<<endl;
}
D.模拟题
找到L左侧的第一个R
找到R右侧的第一个L
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int w[100100];
int R[100100];//从左向右跳,距离最近的L的距离
int L[100100];//从有向左跳,距离最近的R的距离
int ans[100100];
int main(){
string s;
cin>>s;
for( int i=0;i<s.size();i++){
if(s[i]=='L'&&i-1>=0&&s[i-1]=='R'){
L[i]=1;
}
if(s[i]=='R'&&i+1<s.size()&&s[i+1]=='L'){
R[i]=1;
}
}
for( int i=0;i<s.size();i++){//从有向左
if(s[i]=='R') continue;
else{
if(L[i]==0) L[i]=L[i-1]+1;
}
}
for( int i=s.size()-1;i>=0;i--){//从左向右
if(s[i]=='L' ) continue;
else {
if(R[i]==0) R[i]=R[i+1]+1;
}
}
for( int i=0;i<s.size();i++){
if(s[i]=='L'){
int x=i-L[i]+L[i]%2;
ans[x]++;
}
else {
int x=i+R[i]-R[i]%2;
ans[x]++;
}
}
for( int i=0;i<s.size();i++){
printf("%d ",ans[i]);
}
return 0;
}
E。
找到所有因数,然后判断每个因数是否符合答案
判断方法是贪心,每次取最小值加到最大值上
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll w[510];
int n,k;
ll check( ll x){
int cnt=0;
set<pair<ll,ll> >se;
for( int i=1;i<=n;i++){
se.insert(make_pair(w[i]%x,cnt++));
}
ll now=0;
ll res=0;
for( int i=1;i<=n;i++){
if(now<=0) {
set<pair<ll,ll> >::iterator it=se.begin();
ll y=it->first;
se.erase(it);
now+=y;
if(now>0) res+=now;
}
else{
set<pair<ll,ll> >::iterator it=se.end();
it--;
ll y=it->first;
se.erase(it);
now-=(x-y);
if(now<0) res+=-now;
}
}
return res;
}
int main(){
cin>>n>>k;
ll sum=0;
vector<ll>v;
for( int i=1;i<=n;i++){
cin>>w[i];
sum+=w[i];
}
for( int i=1;i*i<=sum;i++){
if(sum%i!=0) continue;
v.push_back(sum/i);
v.push_back(i);
}
ll ans=0;
for( int i=0;i<v.size();i++){
if(check(v[i])<=k){
ans=max(ans,v[i]);
}
}
cout<<ans<<endl;
return 0;
}
F
本题实际上就是求解每个点出现的次数
我们将某个点出现分为两种情况:
第一种情况:该点直接在集合中出现
第二种情况:该点被矩形包围,但是没有在集合中出现
对于第一种情况,使用计数原理直接求解
第二种情况,使用容斥原理加平衡树求解
注意取模
#include<bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const int N=200100;
const ll mod=998244353;
struct Point{
ll x,y;
}p[N];
int cmp(Point a,Point b){
return a.x<b.x;
}
ll onTheLeft_up[N],onTheLeft_down[N],onTheRight_up[N],onTheRight_down[N];
ll powerof2[N];
void cal( ){
powerof2[0]=1;
for( int i=1;i<=200010;i++){
powerof2[i]=powerof2[i-1]*2;
powerof2[i]%=mod;
}
return ;
}
int main(){
int n;
cin>>n;
cal();
for( int i=1;i<=n;i++){
scanf("%lld%lld",&p[i].x,&p[i].y);
}
sort(p+1,p+1+n,cmp);
tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update >t1;
for( int i=1;i<=n;i++){
onTheLeft_down[i]=t1.order_of_key(p[i].y);
onTheLeft_up[i]=t1.size()-onTheLeft_down[i];
t1.insert(p[i].y);
}
tree<ll,null_type,greater<ll>,rb_tree_tag,tree_order_statistics_node_update >t2;
for( int i=n;i>=1;i--){
onTheRight_up[i]=t2.order_of_key(p[i].y);
onTheRight_down[i]=t2.size()-onTheRight_up[i];
t2.insert(p[i].y);
}
ll ans=1ll*n*powerof2[n-1]%mod;//直接包含的情况
//下面计算被覆盖的情况
for( int i=1;i<=n;i++){
ll x=onTheRight_down[i],y=onTheLeft_up[i];
ll a=onTheRight_up[i],b=onTheLeft_down[i];
ans+=(powerof2[x]-1)*(powerof2[y]-1)%mod*(powerof2[a]+powerof2[b]-1);
ans%=mod;
ans+=(powerof2[a]-1)*(powerof2[b]-1)%mod*(powerof2[x]+powerof2[y]-1);
ans%=mod;
ans+=((powerof2[a]-1)*(powerof2[b]-1)%mod)*((powerof2[x]-1)*(powerof2[y]-1)%mod);
ans%=mod;
}
cout<<ans<<endl;
return 0;
}
G.直接算的。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
long long n;
cin>>n;
long long be=1;
long long cnt=n;
long long pow=1;
int flag=0;
while(cnt!=1){
if(cnt%2==0){
if(flag==1){
be+=pow;
}
cnt/=2;
pow*=2;
}
else if(cnt%2==1){
if(flag==1)
be+=pow;
pow*=2;
cnt/=2;
if(flag==1){
flag=0;
}
else {
cnt++;
flag=1;
}
}
}
cout<<be<<endl;
return 0;