A:如果sm是k的倍数,肯定左右删最少的数。删到不是k的倍数的数即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n,x;
cin>>n>>x;
ll sm=0;
for(int i=1;i<=n;i++)cin>>a[i],sm+=a[i];
int mx=-1;
for(int i=1;i<=n;i++)
{
if(a[i]%x!=0)
{
mx=max(mx,n-i);
break;
}
}
for(int i=n;i>=1;i--)
{
if(a[i]%x!=0)
{
mx=max(mx,i-1);
break;
}
}
if(sm%x!=0)
{
cout<<n<<endl;
}
else
{
cout<<mx<<endl;
}
}
return 0;
}
B:
差分和最大,递增或递减序列时差分固定,(只要首末的数选上)
所以我们只保留波浪的峰点即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M];
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++)
cin>>a[i];
bool f=true;
vector<int>v;
v.pb(a[1]);
if(a[2]>a[1])f=true;
else f=false;
for(int i=3;i<=n;i++)
{
if(!f)
{
if(a[i]>a[i-1])
{
v.pb(a[i-1]);
f=true;
}
}
else
{
if(a[i]<a[i-1])
{
v.pb(a[i-1]);
f=false;
}
}
}
v.pb(a[n]);
cout<<v.size()<<endl;
for(int i=0;i<v.size();i++)
cout<<v[i]<<" ";
cout<<endl;
}
return 0;
}
C:
贪心的放即可,题目已经满足a[i]<i,所以一定可以构造出。
先记录最后一个数(肯定是最大的数)所需的数,然后在每个相同数区间的首位放前面一个数需要的最大的数。
比如 1 1 2 2 3 6
我们先放的数为:0 x 1 x 2 3
这样保证每个数都不会在它的时候mex到它。
然后就把需要的集合从小往大放即可。(这个例子需要0 1 2 3 4 5),
0 4 1 5 2 3
放满后其余数补n+1即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
#define in insert
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M],b[M];
int nxt[M];
set<int>s;
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]=-1;
}
for(int i=0;i<a[n];i++)s.in(i);
a[n+1]=a[n]+1;
//for(int i =0;i<=n;i++)nxt[i]=upper_bound(a+1,a+1+n,a[i])-a;
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i-1])
{
b[i]=a[i-1];
s.erase(b[i]);
}
}
for(int i=1;i<=n;i++)
{
if(b[i]==-1)
{
int tp=n+1;
// cout<<i<<" "<<s.size()<<endl;
for(auto x:s)
{
if(x==a[i])continue;
tp=x;
break;
}
s.erase(tp);
b[i]=tp;
}
}
for(int i=1;i<=n;i++)cout<<b[i]<<" ";
cout<<endl;
return 0;
}
D:
这题实现比较简单:
说下思路:
首先如果图是一个树,则:找到一个节点数为k/2的独立集很简单 (直接染色即可)
否则我们一定能找到一个环。
1.如果环大小大于k,则把环断开,拆成点数至少为k的树,可以找到符合条件的独立集
2.小于等于k,找到满足题意的环
到此这题做出来了。。
我们用dfs树找环并判断环大小即可。
后者的做法可以精确判断每个环的大小,方便起见采取后者。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
int T,n,m;
vector<int> vec,ans;
int dep[M],tag[M];
void dfs(int x) {
vec.pb(x);
dep[x] = vec.size();
// cout<<x<<" "<<endl;
for (int i = head[x];i;i = ee[i].nxt)
{
int v = ee[i].to;
if (!dep[v])dfs(v);
else if (dep[x]-dep[v] < T && dep[x]-dep[v]>=2)
{
cout << 2 << endl;
cout << dep[x]-dep[v]+1 << endl;
for (int j = dep[v]-1;j < dep[x];j++)
cout << vec[j] << " ";
cout << endl;
exit(0) ;
}
}
if (!tag[x])
{
ans.pb(x);
for (int i = head[x];i;i = ee[i].nxt)
{
int v = ee[i].to;
tag[v] = 1;
}
}
vec.pop_back();
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m>>T;
for (int i=1;i<=m;i++)
{
int u,v;
cin >> u >> v;
add(u,v,1);
add(v,u,1);
}
dfs(1);
cout << 1 << endl;
for (int i = 0;i < (T+1)/2;i++)
cout << ans[i] << " ";
cout << endl;
return 0;
}