1009 Increasing and Decreasing
题目:
https://vjudge.net/contest/388843#problem/I
思路:
分段和翻转。如一个1 2 3 4 5 6 7 8 9 10的全排列,要构造一个单调递减序列长度为5,只需要将最后五个元素翻转变成1 2 3 4 510 9 8 7 6,在此基础上若再构造一个单调递增序列长度为4,因为前5个数中一定有一个数在单调递增序列最后,所以只需要在前面5个数中选出3个数,那么就可以把前5个数分成3段,然后翻转3段,为了保证字典序最小,就要使前面的段尽可能短。总结一下就是最后y个元素翻转,剩下n-y个元素,将这些元素分为x-1段,保证每段长度大于1且小于等于y。1<=(n-y)/(x-1)<=y;x+y-1<=n<=x*y。
代码:
参考:https://blog.csdn.net/m0_46209312/article/details/107941309
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
int T,n,x,y;
ll ans[maxn],pre[maxn],len[maxn];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&x,&y);
if(1ll*x*y>=n&&x+y<=n+1){
printf("YES\n");
ll res=n-y;
for(int i=1;i<=x-1;i++){//分段
len[i]=res-1ll*(x-1-i)*y;//使前面序列尽可能小
if(len[i]<=0){
len[i]=1;
}
res=res-len[i];
pre[i]=pre[i-1]+len[i];
}
for(int i=1;i<=x-1;i++){
for(int j=pre[i-1]+1;j<=pre[i];j++){
ans[i]=pre[i]-j+pre[i-1]+1;
printf("%d ",ans[i]);
}
}
for(int i=n;i>=n-y+1;i--){//翻转
printf("%d%c",i,i==n-y+1?'\n':' ');
}
}else{
printf("NO\n");
}
}
return 0;
}
1010 Jogging
题目:
https://vjudge.net/contest/388843#problem/J
思路:
代码:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int ux[] = {1, 1, 1, 0, 0, -1, -1, -1};
const int uy[] = {1, 0, -1, 1, -1, 1, 0, -1};
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
void calc(i64 x0, i64 y0){
static const int C = 20000;
int deg = 0, ord = 0;
queue<pair<int, int>> q;
set<pair<int, int>> vis;
q.emplace(0, 0);
vis.emplace(0, 0);
while (q.size()) {
if (ord > C)
{
deg=0;ord=1;
goto tag;
}
int dx, dy;
tie(dx, dy) = q.front();
q.pop();
++ord;
for (int dir = 0; dir < 8; ++dir) {
int dx0 = dx + ux[dir];
int dy0 = dy + uy[dir];
if (__gcd(x0 + dx0, y0 + dy0) > 1) {
++ord;
if (vis.count(make_pair(dx0, dy0))) {
continue;
}
vis.insert(make_pair(dx0, dy0));
q.emplace(dx0, dy0);
}
}
if (!deg) deg = ord;
}
if (!ord)deg=1,ord=1;
tag:;
int tp=gcd(deg,ord);
deg/=tp;ord/=tp;
cout<<deg <<"/"<< ord<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;
for(cin>>T;T;--T){
i64 x,y;
cin>>x>>y;
calc(x,y);
}
}
比赛:https://paste.ubuntu.com/p/Gw6kShypVP/