next_permutation c++全排列函数用法
next_permutation()全排列函数
·. next_permutation(start,end)返回下一个排列
·. prev_permutation(start,end)返回上一个排列(均按字典序排序)
当当前序列(数组)不存在下一个排列时,函数返回false,否则返回true
next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
此外,next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。也可以对字符按照字典序排列。
例: https://codeforces.com/group/L9GOcnr1dm/contest/514966/problem/D
D. Evil Coordinate
在一个图中,一个人从(0,0)进行上下左右行走。有一个地雷点(mx,my)。询问可不可以通过改变行走上下左右的顺序(不改变上下左右走的次数),可以避开雷。如果有多个,输出任意一种,如果没有,输出Impossible!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>
priority_queue<int,vector<int>,greater<int>>qmi;//大根堆
priority_queue<int>qma;//小根堆
const int mod = 1e09+7;
const int maxn = 100+10;
int gcd(int a,int b)
{
return b>0?gcd(b,a%b):a;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int mx,my;
int a[4]={0,1,2,3};
int cnt[4]={0};
int op[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
bool check(){//按照排列后的顺序行走,每个方向都走到头。因为总有路是路径不重叠的。
int x,y;
x=y=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<cnt[a[i]];j++)
{
x+=op[a[i]][0];
y+=op[a[i]][1];
if(x==mx && y==my)
return false;
}
}
return true;
}
map<int,string>mp={{0,"U"},{1,"D"},{2,"L"},{3,"R"}};
void solve(){
cin>>mx>>my;
string s;
cin>>s;
int x=0,y=0;
memset(cnt,0,sizeof(cnt));
a[0]=0,a[1]=1,a[2]=2,a[3]=3;
for(int i=0;i<s.size();i++)
{
if(s[i]=='U')
{
cnt[0]++;
y++;
}if(s[i]=='D')
{
cnt[1]++;
y--;
}if(s[i]=='L')
{
cnt[2]++;
x--;
}if(s[i]=='R')
{
cnt[3]++;
x++;
}
}
if((mx==0 and my==0)or(x==mx and y==my))//特判在起点和终点
{
cout<<"Impossible"<<endl;
return;
}
bool ok=false;
do
{
if(check())
{
ok=true;
for(int i=0;i<4;i++)
{
for(int j=0;j<cnt[a[i]];j++)
{
cout<<mp[a[i]];
}
}
cout<<endl;
break;
}
}while(next_permutation(a,a+4)); //对序列进行全排列,每次都分析情况。
if(!ok)
{
cout<<"Impossible"<<endl;
}
}
signed main() {
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}