Codeforces Round #720 (Div. 2) [未完待续]
A. Nastia and Nearly Good Numbers
参考题解
x + y = z, 两边把因子A消去 =>
x/A + y/A = z/A
要求其中只有一个可以含有因子B, 可以如下构造:
x/A = B, y/A = B+1, z/A = 2B+1
当B不为1时用数论知识很容易得到B+1无因子B, 2B+1不含因子B
(证明方法注: B+1 === 2B+1 === 1 (mod B), '==='表示同余)
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int main()
{
int t;
cin >> t;
while(t --)
{
int A, B;
scanf("%d%d", &A, &B);
if(B == 1)
{
printf("NO\n");
}
else
{
printf("YES\n");
printf("%lld %lld %lld\n", A*(LL)B, A*(LL)(B+1), A*(LL)(2*B+1));
}
}
return 0;
}
B. Nastia and a Good Array
参考题解
从最小数的位置开始往两边自增1,构造题
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#define x first
#define y second
using namespace std;
const int N = 1e5+5, INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> PII;
int n;
int a[N];
int gcd(int a, int b)
{
return b ? gcd(b, a%b) : a;
}
struct RES
{
int i, j, x, y;
} res[N];
int main()
{
int t;
cin >> t;
while(t --)
{
int ans = 0;
cin >> n;
int minidx = -1;
for(int i = 0; i < n; ++ i)
{
scanf("%d", a+i);
if(minidx == -1 || a[i] < a[minidx])
{
minidx = i;
}
}
for(int i = minidx-1; i >= 0; -- i)
{
res[ans++] = {i, minidx, a[i+1]+1, a[minidx]};
a[i] = a[i+1] + 1;
}
for(int i = minidx+1; i < n; ++ i)
{
res[ans++] = {minidx, i, a[minidx], a[i-1]+1};
a[i] = a[i-1] + 1;
}
printf("%d\n", ans);
for(int i = 0; i < ans; ++ i)
{
printf("%d %d %d %d\n", res[i].i+1, res[i].j+1, res[i].x, res[i].y);
}
}
return 0;
}
C. Nastia and a Hidden Permutation
参考题解
感谢大佬提供的思路
自己的思路图

#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
const int N = 1e4+5;
int n;
int ask(int t, int i, int j, int x)
{
printf("? %d %d %d %d\n", t, i, j, x);
cout.flush();
int res = -1;
scanf("%d", &res);
return res;
}
int ans[N];
int main()
{
int t;
cin >> t;
while(t --)
{
memset(ans, 0, sizeof(ans));
scanf("%d", &n);
for(int i = 1; i <= n/2; ++ i)
{
int a = i, b = i+n/2;
//计算maxv
int maxv = -1;
int t = ask(1, a, b, n-1);
if(t == -1) return 0; //错误
if(t == n-1)
{
int tp = ask(2, a, b, n-1);
if(tp == -1) return 0;
if(tp == n)
{
ans[a] = n;
}
else
{
maxv = t;
}
}
else
{
maxv = t;
}
if(maxv == -1) //已经计算ans[a]
{
ans[b] = ask(2, b, a, 1);
if(ans[b] == -1) return 0;
continue;
}
//计算minv
int minv = -1;
t = ask(2, a, b, 1);
if(t == -1) return 0;
if(t == 2)
{
int tp = ask(1, a, b, 1);
if(tp == -1) return 0;
if(tp == 1)
{
ans[b] = 1;
}
else
{
minv = t;
}
}
else
{
minv = t;
}
if(minv == -1) //已经计算了ans[b]
{
ans[a] = ask(1, b, a, n-1);
if(ans[a] == -1) return 0;
continue;
}
//计算结果
t = ask(2, a, b, minv);
if(t == -1) return 0;
if(t == minv)
{
ans[a] = minv;
ans[b] = maxv;
}
else
{
ans[a] = maxv;
ans[b] = minv;
}
}
if(n%2==1)
{
set<int> ha;
for(int i = 1; i <= n/2*2; ++ i)
{
ha.insert(ans[i]);
}
for(int i = 1; i <= n; ++ i)
{
if(ha.count(i) == 0)
{
ans[n] = i;
break;
}
}
}
printf("!");
for(int i = 1; i <= n; ++ i)
{
printf(" %d", ans[i]);
}
printf("\n");
cout.flush();
}
return 0;
}








浙公网安备 33010602011771号