题意:
给一个1 ~ n全排列组成的数组,任意找一个左端点l和右端点r,将l ~ r区间的数反转一下,求得到字典序最小的新数组
#include
#include
#include
using namespace std;
#define int long long
int a[510];
void solve()
{
int n;
scanf("%lld",&n);
for(int i=1;i<=n;i++)cin>>a[i];
int l=1,r=1;
for(int i=1;i<=n;i++)
{
if(a[i]>i)
{
l=i;
break;
}
}
for(int i=1;i<=n;i++)
{
if(a[i]==l)
{
r=i;
break;
}
}
for(int i=1;i<l;i++)cout<<a[i]<<" ";
for(int i=r;i>=l;i--)cout<<a[i]<<" ";
for(int i=r+1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
}
signed main()
{
int T;
scanf("%lld",&T);
while(T--)solve();
}
题意:
给一组数,当相邻两个数之和为奇数时可以交换,问能否通过若干次操作,使原数组变为不降序列
思路:
奇偶性判断即可,如果前边出现比后边大的必须要交换到后边,但同为偶数或者同为奇数,则不能交换,所以把数组分为奇数和偶数序列,如果奇数和偶数都不降则满足要求
#include
#include
#include
using namespace std;
#define int long long
const int N = 100010;
int a[N];
void solve()
{
int n;
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",a+i);
bool f=true;
int maxv1=0,maxv2=0;
for(int i=1;i<=n;i++)
{
if(a[i]&1)
{
if(maxv1>a[i])
{
f=false;
break;
}
maxv1=a[i];
}
else
{
if(maxv2>a[i])
{
f=false;
break;
}
maxv2=a[i];
}
}
if(f)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main()
{
int T;
scanf("%lld",&T);
while(T--)solve();
}
题意:
一个由1~n全排列组成的数组p
如果满足 i < j 且 p i > p j i < j 且pi > pj i<j且pi>pj则i和j连一条边,问最后有几个连通块
思路:
很容易找到一个性质:
如果一个数前边有比它大的数则一定在那个大的数的连通块里
又因为是全排列,我们直接遍历就行了
#include
#include
#include
using namespace std;
const int N = 100010;
int a[N];
int n;
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",a+i);
int res=0;
int maxv=0;
for(int i=1;i<=n;i++)
{
if(maxv<i)res++;
maxv=max(maxv,a[i]);
}
cout<<res<<endl;
}
signed main()
{
int T;
scanf("%d",&T);
while(T--)solve();
}
思路很简单关键是实现
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
void solve()
{
int n,m;
cin>>n>>m;
vector<vector<int>>a(n+1);
for(int i=1;i<=n;i++)
{
a[i].resize(m+1);
for(int j=1;j<=m;j++)cin>>a[i][j];
}
auto equal = [&](int x,int y)
{
int col=0;
if(x<=0||x>=n||y<=0||y>=m)return make_pair(false,col);
set<int>s;
for(auto it:{a[x][y],a[x+1][y],a[x][y+1],a[x+1][y+1]})
if(it!=-1)s.insert(it),col=it;
return make_pair(s.size()==1,col);
};
auto paint = [&](int x,int y,int col)
{
a[x][y]=a[x+1][y]=a[x][y+1]=a[x+1][y+1]=col;
};
queue<tuple<int,int,int>>q;
vector<tuple<int,int,int>>path;
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
{
auto [res,col] = equal(i,j);
if(res)
{
q.push({i,j,col});
path.push_back({i,j,col});
paint(i,j,-1);
}
}
while(q.size())
{
auto [x,y,val] = q.front();
q.pop();
for(int i=x-1;i<=x+1;i++)
for(int j=y-1;j<=y+1;j++)
{
auto [res,col] = equal(i,j);
if(res)
{
q.push({i,j,col});
paint(i,j,-1);
path.push_back({i,j,col});
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]!=-1)
{
cout<<-1<<'\n';
return ;
}
reverse(path.begin(),path.end());
cout<<path.size()<<'\n';
for(auto [x,y,col] : path)
cout<<x<<" "<<y<<" "<<col<<'\n';
}
signed main()
{
int T;
T=1;
while(T--)solve();
}