A:给一个数n操作k次,对于每次:如果n%10==0,n/=10,否则n--。
模拟
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 5e5+5;
int main(){
int n,k;scanf("%d%d",&n,&k);
while(k--){
if(n%10==0)n/=10;
else n--;
}
printf("%d",n);
return 0;
}
B:给一个字符串,求出现最多的2元串
直接map,key为二元串,value为出现次数。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 5e5+5;
map<string,int>m;
map<string,int>::iterator it;
int main(){
int n;string s;cin>>n>>s;
for(int i=0;i<n-1;i++){
string t;t=t+s[i];t=t+s[i+1];m[t]++;
}
int ans=0;string u;
for(auto it:m){
if(ans<(it.second)){ans=it.second;u=it.first;}
}
cout<<u;
return 0;
}
C:给一个数组,求是否一个x,x在【1,1e9】内,并且恰好有k个元素小于等于x。
注意判断k==0以及k==n,然后对于其他的数,sort后判断a[k]!=a[k+1]是否成立即可。输出的时候输出a[k]即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 2e5+5;
int a[MXN]={1};
int main(){
int n,k;cin>>n>>k;for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+1+n);
if(k==n)printf("%d",a[k]);
else if(a[k]==a[k+1])printf("-1");
else printf("%d",a[k]);
return 0;
}
D:先给定一个数n,对于n可以有两种操作,n*=2,n/=3(n能整除3),操作n-1次得到n个数,打乱顺序后,让还原。
解法1:dfs裸题,满足要求就dfs下去即可,因为每次满足的不会有很多,甚至没有,所以dfs树分枝会很少。
解法2:先找出第一个数(3最多,2最少),然后找可以变成的数即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 2e5+5;
LL n,a[105];
LL path[105];bool vis[105],is_found;
void dfs(int ro){
if(is_found)return;
if(ro==n+1){is_found=1;return;}
for(int i=1;i<=n;i++){
if(is_found)break;
if(vis[i])continue;
if(ro==1||(path[ro-1]%a[i]==0LL&&path[ro-1]/a[i]==3LL)||(a[i]%path[ro-1]==0&&a[i]/path[ro-1]==2LL)){
vis[i]=1;path[ro]=a[i];
dfs(ro+1);
vis[i]=0;
}
}
}
int main(){
scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
dfs(1);
for(int i=1;i<=n;i++)printf("%lld ",path[i]);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long //!
#define pai acos(-1)
//const LL mod = 1000000007;
const int MXN = 2e5+5;
int a[105];bool vis[105];
vector<int>v;
int f(int x,int c){
int p=0;while(x%c==0){p++;x/=c;}return p;
}
signed main(){ //!
int n;scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
int mi=INT_MAX,u;
for(int i=1;i<=n;i++){
int cnt=f(a[i],2);
if(cnt<mi){mi=cnt,u=i;}
}
for(int i=1;i<=n;i++){
int cnt=f(a[i],2);
if(cnt==mi)
v.push_back(i);
}
int mx=-1;
for(auto i:v){
int cnt=f(a[i],3);
if(cnt>mx){mx=cnt,u=i;}
}
cout<<a[u];vis[u]=1;int last=a[u];
for(int z=2;z<=n;z++){
for(int i=1;i<=n;i++){
if(vis[i])continue;
if(a[i]%last==0&&a[i]/last==2){
printf(" %lld",a[i]);vis[i]=1;last=a[i];
}
if(last%a[i]==0&&last/a[i]==3){
printf(" %lld",a[i]);vis[i]=1;last=a[i];
}
}
}
return 0;
}
E:求一张图里有几个单纯环(即一个联通块只能是一个环,不能有别的多余边
用并查集维护,对于属于一个联通块的,判断度是否为2即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 2e5+5;
int fa[MXN],du[MXN];
int found(int x){
if(fa[x]==x)return x;
return fa[x]=found(fa[x]);
}
vector<int>v[MXN];
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
int u,v;scanf("%d%d",&u,&v);
du[u]++,du[v]++;
int fu,fv;fu=found(u);fv=found(v);
if(fu!=fv) fa[fu]=fv;
}
for(int i=1;i<=n;i++){
v[found(i)].push_back(i);
}int ans=0;
for(int i=1;i<=n;i++){
if(v[i].size()<=2)continue;
int tag=1;
for(auto it:v[i]){
if(du[it]!=2){tag=0;break;}
}
if(tag) ans++;
}
printf("%d",ans);
return 0;
}
F:给一个数组,求lcs,但是相邻两项差1。
my解法1:dp,用前i位更新第i位,set存第i位之前的信息,对于第i位,在set找满足题意的节点,然后更新dp,用链表存储前躯。
解法2:mp离散化,(mp真好使
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 2e5+5;
struct no{int u,val,dd;};
bool operator<(const no &x,const no &y){
if(x.val==y.val)return x.dd<y.dd;
return x.val<y.val;
}
int a[MXN];
int dp[MXN],pre[MXN];
multiset<no>s;multiset<no>::iterator it;
vector<int>ans;
int main(){
int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
dp[1]=1,pre[1]=-1;s.insert(no{1,a[1],1});
for(int i=2;i<=n;i++){
no now=no{i,a[i]-1,INT_MAX};
it=s.upper_bound(now);
if(it==s.begin()){
dp[i]=1;pre[i]=-1;s.insert(no{i,a[i],dp[i]});
continue;
}
it--;
if(it->val!=a[i]-1){
dp[i]=1;pre[i]=-1;s.insert(no{i,a[i],dp[i]});
continue;
}
dp[i]=it->dd+1;pre[i]=it->u;
s.insert(no{i,a[i],dp[i]});
}
int mx=0,u;
for(int i=1;i<=n;i++){
if(dp[i]>mx){mx=dp[i],u=i;}
}
printf("%d\n",mx);
for(int i=u;i!=-1;i=pre[i])ans.push_back(i);
for(int i=ans.size()-1;i>=0;i--)printf("%d ",ans[i]);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 2e5+5;
int a[MXN];
map<int,int>dp;
int main(){
int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)dp[a[i]]=dp[a[i]-1]+1;
int mx=0,ed;
for(auto it:dp){
if(it.second>mx){mx=it.second;ed=it.first;}
}
int st=ed-mx+1;
printf("%d\n",mx);
for(int i=1;i<=n;i++){
if(a[i]==st){printf("%d ",i);st++;}
}
return 0;
}