九进制转十进制
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
//#define int long long
using namespace std;
void solve(){
int n=2022;
int ans=0;
int t=1;
while(n){
ans+=(n%10)*t;;
n/=10;
t*=9;
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
每位的数字乘9^(位数),再相加即可
顺子日期
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
//#define int long long
using namespace std;
void solve(){
cout<<14<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
20221230,20221231,20221123,20221012,2022012(0到9),总共14个
刷题统计
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;
void solve(){
int a,b,n;
cin>>a>>b>>n;
int temp=a*5+b*2;
int ans=(n/temp)*7;
n%=temp;
if(n>0) loop(i,1,5){
ans++;
n-=a;
if(n<=0) break;
}
if(n>0) loop(i,1,2){
ans++;
n-=b;
if(n<=0) break;
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
先算出前面完整的一周完成的作业数记录到ans里,然后特判最后不完整的一周,加到ans里,输出ans
修剪灌木
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;
void solve(){
int n;cin>>n;
loop(i,1,n/2){
cout<<(n-i)*2<<'\n';
}
loop(i,(n/2)+1,n){
cout<<(i-1)*2<<'\n';
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
每棵树最高长到max(这个树到左边的距离,这个数到右边的距离)*2
X进制减法
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;
inline int Mod(int x){
while(x<0) x+=mod;
return x%mod;
}
void solve(){
int n;cin>>n;
int pw=1;
int na,nb;
cin>>na;
ve<int> a(na+1);
loop(i,1,na) cin>>a[i];
cin>>nb;
ve<int> b(nb+1);
loop(i,1,nb) cin>>b[i];
int ans=0;
loop(i,1,max(na,nb)){
if(i<=na&&i<=nb){
int temp=max(2ll,max(a[na-i+1],b[nb-i+1])+1);
ans=Mod(ans+(a[na-i+1]-b[nb-i+1])*pw);
pw=Mod(pw*temp);
continue;
}
if(i<=na){
ans=Mod(ans+(a[na-i+1])*pw);
pw=Mod(pw*max(a[na-i+1]+1,2ll));
}
if(i<=nb){
ans=Mod(ans+(b[nb-i+1])*pw);
pw=Mod(pw*max(b[nb-i+1]+1,2ll));
}
}
cout<<ans<<'\n';
}
signed main(){
//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
每位的进制数取到能取的最小值,最后结果就最小,因为假设从高位到低位,第一个不同的数(a[i1]-b[i1])必然大于0,第二个不同的数(a[i2]-b[i2])就算小于0,加上(a[i1]-b[i1])也会大于0,依此类推,那么让每个进制取最小,求和就最小
统计子矩阵
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
using namespace std;
int a[510][510];
int s(int e,int b,int c,int d){
return a[c][d]-a[e-1][d]-a[c][b-1]+a[e-1][b-1];
}
void solve(){
int n,m,k;
cin>>n>>m>>k;
loop(i,1,n){
loop(j,1,m){
cin>>a[i][j];
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
int ans=0;
loop(i,1,n){
loop(j,i,n){
int tt=0;
loop(t,1,m){
while(tt<t||(s(i,t,j,tt)<=k&&tt<=m)) tt++;
ans+=tt-t;
}
}
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
用二维前缀和存矩阵a,然后枚举i,j,t,tt为矩阵的四个顶点,但是O(n4)超时,所以后两个指针用双指针优化O(n3)能过
积木画
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;
void solve(){
int n;cin>>n;
ve<int> dp(4);
dp[0]=1;
dp[1]=1;
loop(i,2,n){
ve<int> g(4);
g[0]=dp[1];
g[1]=(dp[1]+dp[2]+dp[3]+dp[0])%mod;
g[2]=(dp[0]+dp[3])%mod;
g[3]=(dp[0]+dp[2])%mod;
swap(dp,g);
}
cout<<dp[1]<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
考虑dp,g为dp的下一层,dp[0]为最末尾一列没有积木,dp[1]为最后一列满积木,dp[2],为最后一列上面有积木,dp[3]为最后一列下面有积木,可以推出上面的dp转移
扫雷
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define N 500004
#define NN 50004
using namespace std;
int head[N],nxt[N],edge[N],ind;
bool check[NN];
int num[NN],rr[NN];
int ans;
unordered_map<int,int> mp;
void add(int a,int b){
nxt[++ind]=head[a];
head[a]=ind;
edge[ind]=b;
}
int query(int x,int y){
int key=x*1000000001+y;
if(mp.count(key)) return mp[key];
else return 0;
// int t=((key%N)+N)%N;
// for(int i=head[t];i;i=nxt[i]){
// if(edge[i]==key) return i;
// }
// return 0;
}
void insert(int x,int y){
int key=x*1000000001+y;
mp[key]=++ind;
edge[ind]=key;
//int t=((key%N)+N)%N;
//add(t,key);
}
void dfs(int x){
ans+=num[x];
check[x]=1;
int dx=edge[x]/1000000001;
int dy=edge[x]%1000000001;
loop(i,-rr[x],rr[x]){
loop(j,-rr[x],rr[x]){
int temp=query(dx+i,dy+j);
if(i*i+j*j<=rr[x]*rr[x]&&temp&&check[temp]==0){
dfs(temp);
}
}
}
}
void solve(){
int n,m;
cin>>n>>m;
loop(i,1,n){
int x,y,r;
cin>>x>>y>>r;
if(query(x,y)==0) insert(x,y);
rr[query(x,y)]=max(rr[query(x,y)],r);
num[query(x,y)]++;
}
loop(i,1,m){
int x,y,r;
cin>>x>>y>>r;
loop(j,-r,r){
loop(k,-r,r){
int temp=query(x+j,y+k);
if(j*j+k*k<=r*r&&temp&&check[temp]==0){
dfs(temp);
}
}
}
}
cout<<ans<<'\n';
}
signed main(){
//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
用map把坐标映射成数字(1,2,3…),然后枚举每一颗雷的射程范围,用dfs把雷清空
李白打酒加强版
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
#define mod 1000000007
using namespace std;
int dp[110][110][110];
void solve(){
memset(dp,0,sizeof(dp));
int n,m;
cin>>n>>m;
dp[0][0][2]=1;
loop(i,0,n){
loop(j,0,m){
loop(k,0,110){
if(i&&(k%2==0)) dp[i][j][k]+=dp[i-1][j][k/2];
dp[i][j][k]%=mod;
if(j) dp[i][j][k]+=dp[i][j-1][k+1];
dp[i][j][k]%=mod;
}
}
}
cout<<dp[n][m-1][1]<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;cin>>t;
while(t--) solve();
return 0;
}
考虑dp,dp[店的数量][花的数量][剩余的酒],有转移dp[i][j][k]+=dp[i-1][j][k/2],dp[i][j][k]+=dp[i][j-1][k+1]
最后输出dp[n][m-1][1]
砍竹子
#include<bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
#define loopn(i,a,b) for(int i=a;i>=b;i--)
#define ve vector
#define pb push_back
#define pob pop_back
#define int long long
const int N = 2e5 + 10;
using namespace std;
int a[N][20];
int f(int x){
return sqrt(x/2+1);
}
void solve(){
int n;cin>>n;
int ans=0;
loop(i,1,n){
int temp;cin>>temp;
int t[20],top=0;
while(temp>1){
t[top++]=temp;
temp=f(temp);
}
ans+=top;
int top2=0;
while(top){
a[i][top2++]=t[--top];
}
}
loop(i,1,n){
loop(j,0,15){
if(a[i][j]!=0&&a[i][j]==a[i+1][j]) ans--;
}
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;//cin>>t;
while(t--) solve();
return 0;
}
用a[N][20]存下每颗树每次被砍的高度,显然被砍不多次就会变1,所以20够存,如果a[i][j]==a[i][j+1],就可以少砍一次