算法
CF955 1982
https://codeforces.com/contest/1982
1 数学思维
/*
我们无需考虑一直加1,而是加一个数到y的倍数这样简化的去想。
*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin>>t;
while(t--)
{
int x,y,k;
cin>>x>>y>>k;
while(1)
{
if(x==1||k==0)
//优化:当x=1;一定是加到y,然后y/y=1重复这个过程
break;
int s=min(k,y-(x%y));
x+=s;
k-=s;
while(x%y==0)
x/=y;
}
k=k%(y-1);
x+=k;
cout<<x<<endl;
}
return 0;
}
2 双指针
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=2e6+100;
int t;
int a[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
int l,r,n;
cin>>n>>l>>r;
for(int i=1;i<=n;i++) cin>>a[i];
int ll=1,rr=0,ans=0,sum=0;
while(ll<=n&&rr<=n){//保证不越界
if(sum>=l&&sum<=r){//满足题目要求
ll=rr+1;//更新区间左端点
ans++;//答案++
sum=0;//清零区间和
}
else if(sum<l){
rr++;
sum+=a[rr];//将此数加入当前区间
}
else if(sum>r){
sum-=a[ll];//将此数提出当前区间
ll++;
}
}
cout<<ans<<endl;
}
return 0;//养成好习惯
}
3 数论(裴蜀定理)+二维差分
不太懂这个c的计算
//ax+by=c;其中一定是c一定是gcd(a ,b)的倍数,即最大公因数的倍数,适用于n阶
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=505;
int t,n,m,k,a[N][N],s[N][N],sa,sb,b[N][N];
signed main()
{
ios::sync_with_stdio(0);
cin>>t;
while (t--)
{
cin>>n>>m>>k;
sa=sb=0;
k--;
for (int i=1; i<=n; i++)
{
for (int j=1; j<=m; j++)
{
cin>>b[i][j];
}
}
for (int i=1; i<=n; i++)
{
for (int j=1; j<=m; j++)
{
char x;
cin>>x;
a[i][j]=x-'0';
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
//有雪格子的数量
if (a[i][j]==0) sa+=b[i][j];//无雪高度和
else sb+=b[i][j];//有雪高度和
}
}
sa=abs(sa-sb);
sb=0;
for (int i=1; i+k<=n; i++)
{
for (int j=1; j+k<=m; j++)
{
int siz=s[i+k][j+k]-s[i-1][j+k]-s[i+k][j-1]+s[i-1][j-1];
//以i,j为左上角的k×k 子矩阵的有雪格子数量
sb=__gcd(sb,abs((k+1)*(k+1)-siz-siz));
//后面的那个数就是ci
//为啥不是k*k-siz??
}
}
//cout<<sa<<" "<<sb<<endl;
if (sb==0)
{
if (sa==0) cout<<"YES\n";//也就是最初高度正好是想要的
else cout<<"NO\n";
continue;
}
if (sa%sb==0) cout<<"YES\n";//sa是c的最大公因数sb的倍数
else cout<<"NO\n";
}
return 0;
}
vj1
https://vjudge.net/contest/651665#overview
https://blog.csdn.net/m0_46596968/article/details/121341177
1 位运算(异或,与)
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
long long ans;
long long a,b;
cin>>a>>b;
ans=a&b;
if(ans==0)
cout<<1<<endl;
else
cout<<ans<<endl;
}
}
2 思维转化,stl
/*应该逆向思维,第一个输出的数一定是最后调整的,先入后出用栈实现,再利用vis标记,输出其他没有调整过的*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
bool vis[maxn];
stack<int>s;
int n,m;
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
cin>>a[i];
while(m--)
{
int x;
cin>>x;
s.push(x);
}
while(!s.empty())
{
int x=s.top();
s.pop();
if(vis[x])
continue;
cout<<x<<" ";
vis[x]=1;
}
for(int i=1; i<=n; i++)
{
if(vis[i]==0)
cout<<a[i]<<" ";
}
}
3 图形模拟
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=(1<<10)+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
char a[N][N],b[N][N];
int main()
{
int t;
scanf("%d",&t);
a[1][1]=a[1][2]=a[2][2]='C',a[2][1]='P';
while(t--)
{
int n;
scanf("%d",&n);
int k=2;
for(int i=2; i<=n; i++,k<<=1)
{
for(int j=1; j<=k; j++)
{
for(int l=1; l<=k; l++)
{
b[j][l]=a[j][l];
}
}
for(int j=1; j<=k; j++)
{
for(int l=1; l<=k; l++)
{
b[j][l+k]=a[j][l];
}
}
for(int j=1; j<=k; j++)
{
for(int l=1; l<=k; l++)
{
b[j+k][l]=(a[j][l]=='C')?'P':'C';
}
}
for(int j=1; j<=k; j++)
{
for(int l=1; l<=k; l++)
{
b[j+k][l+k]=a[j][l];
}
}
swap(a,b);
}
for(int i=1; i<=k; i++)
{
for(int j=1; j<=k; j++)
printf("%c",a[i][j]);
puts("");
}
}
return 0;
}
贪心
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 1; i <= n; ++i)
const int N = 1E5 + 10;
int a[N];
int main()
{
int t; cin >> t;
while (t--) {
vector<int> b; //放剩余时间
int n, m; scanf("%d %d", &n, &m);
ll res = m; int cou = 1; //起初我们至少要m的时间, 抓一条鱼
rep(i, n) scanf("%d", &a[i]), res += a[i], cou += a[i] / m, b.push_back(a[i] % m);
sort(b.begin(), b.end(), greater<int>());
for (int i = 1; i <= n - cou; ++i) res += m - b[i - 1];
cout << res << endl;
}
return 0;
}