标签:sdi range include fflush 思路 sync 题意 device problem
两个人各持有\(k_1\)、\(k_2\)张牌,牌序号唯一且在范围\(1\)~\(n\)其中\(n=k_1+k_2\)。一次操作两个各亮出一张牌,谁牌序号大,谁拿对方的牌,最后没牌者输,问先手是否必赢。
很显然谁持有最大牌谁赢......
但是\(tourist\)能在一分钟内读完题并敲好代码提交过了真是太强了。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int n,k1,k2;
int main(void) {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int kase; read(kase);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
read(n);
read(k1);
read(k2);
bool qwq=false;
for(int u,i=1;i<=k1;++i){
read(u);
if (u==n) qwq=true;
}
for(int u,i=1;i<=k2;++i){
read(u);
}
if (qwq) printf("YES\n");
else printf("NO\n");
}
return 0;
}
给定一个长度为\(n\)的数组\(a\),问是否存在某个区间\([l,r]\),有\(max-min\geq k\),其中\(max=\max\limits_{i \in [l,r]}(a_i)\),\(min=\min\limits_{i \in [l,r]}(a_i)\),\(k=r-l+1\),存在则输出\(YES\)并输出任意一个符合要求的区间,否则输出\(NO\).
我们考虑一个符合题目条件的区间\([l,r]\),其中最大值和最小值在端点处是最优的选择,不失一般性,我们设最大值在\(r\)处,最小值在\(l\)处,则\(max-min=(max_1-max_2)+(max_2-max_3)+...+(max_{k-1}-max_k)=\geq k\),从中我们可以看出至少有一个\(max_i-max_{i+1}>1\),才能有该不等式成立,那也一定有至少一个位置\(i\)有\(abs(a_i-a_{i+1})\geq 2\)才行。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int n,u,v;
int main(void) {
//ios::sync_with_stdio(false);
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int kase; read(kase);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
read(n);
read(u);
bool qwq=false;
int l=0;
for(int i=2;i<=n;++i){
read(v);
if (ABS(v-u)>1) {qwq=true;l=i-1;}
u=v;
}
if (qwq) printf("YES\n%d %d\n",l,l+1);
else printf("NO\n");
}
return 0;
}
给定\(n\)个正整数,设\(n\)个数的和为\(sum\),异或为\(x\),若\(sum=2x\)则这个序列是\(good\)的,如果不是\(good\),最多可增加三个正整数,使得这个序列变成\(good\),求添加数的个数以及数的大小。
首先\(sum\)一定要是偶数,否则我们先加一个数\(1\),然后再考虑\(sum\)和\(x\)大小。
注意到异或两次同一个数相当于不变,那么如果\(sum<2x\),那么我们只要再增加两个同样的数\(qwq=\dfrac{2x-sum}{2}\),这样\(x\)不变,而\(sum\)也变成了\(2x\)。
如果\(sum>2x\),我们再一开始增加一个超大超大的数,让\(sum<2x\)即可,由于\(sum\leq 10^{15}\),那我们就增加一个\(10^{16}\)的数,即\(2^{50}\),如果\(sum\)是奇数,就加\(2^{50}+1\),然后根据上面的情况即可。
对应代码为注释部分。
这题还有另一种加法,即加两个数\(x\)和\(sum+x\),这样和就变成\(2(sum+x)\),异或值变成\(sum+x\),这样也符合题意。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int main(void) {
//ios::sync_with_stdio(false);
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int kase; read(kase);
for (int i = 1; i <= kase; i++) {
//printf("Case #%d: ", i);
int n;
LL sum,xx,u,a;
read(n);
sum=xx=0;
for(int i=1;i<=n;++i){
read(u);
sum+=u;
xx=xx^u;
}
printf("2\n%lld %lld\n",xx,xx+sum);
/* if ((xx<<1ll)==sum) printf("0\n\n");
else{
a=(1ll<<50ll);
if (sum&1ll) a=a|1ll;
sum+=a;
xx=(xx^a);
xx<<=1;
LL qwq=xx-sum;
printf("3\n%lld %lld %lld\n",a,(qwq>>1),(qwq>>1));
} */
}
return 0;
}
交互题。
给定\(n\)和\(k\),以及一个你并不知道长度为\(n\)的数俩俩不同的数列和\(m\),每次你可以问\(k\)个互不相同的下标,对方会告诉你这些下标对应的值里,从小到大排列第\(m\)个小数的位置和值。不能问多于\(n\)次。最后你的程序要猜出\(m\)值。
一开始妄图想找到\(k\)个数然后问它们一波得到\(m\)值结果不可行。然后妄图用并查集维护每个数在\(m\)的左边还是右边发现数太多了不可控\(qwq\)所以我们要考虑少点的数,比如就前\(k+1\)个数,每次我们选这其中的\(k\)个数,相当于把其中的一个数从\(k+1\)个数中剔除,然后我们考虑这个剔除的数对第\(m\)个数的影响。
假设在这\(k+1\)个数中,第\(m\)个数的值为\(a\),则如果剔除的一个数\(i\)小于等于\(a\),则第\(m\)个数会变成另一个数\(b\),如果大于\(a\),则第\(m\)个数还是\(a\)。纵观我们剔除\(k+1\)次的结果,可以知道数\(a\)会出现\(k+1-m次\),而数\(b\)会出现\(m\)次,于是我们统计较大的数出现的次数就是答案\(m\)。
神奇的代码
#include <bits/stdc++.h>
#define MIN(a,b) ((((a)<(b)?(a):(b))))
#define MAX(a,b) ((((a)>(b)?(a):(b))))
#define ABS(a) ((((a)>0?(a):-(a))))
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<PII> VPII;
typedef vector<LL> VL;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int main(void) {
//ios::sync_with_stdio(false);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int n,k;
read(n);
read(k);
vector<bool> sign(k+2,false);
int ma=0,cnt=0;
for(int i=1;i<=k+1;++i){
sign[i]=true;
sign[i-1]=false;
printf("? ");
for(int j=1;j<=k+1;++j) if (!sign[j]) printf("%d ",j);
puts("");
fflush(stdout);
int u,v;
read(u);read(v);
if (ma<v){cnt=1;ma=v;}else if (ma==v) ++cnt;
}
printf("! %d\n",cnt);
fflush(stdout);
return 0;
}
May 2020 will be the year of high ratings for the hard workers.
标签:sdi range include fflush 思路 sync 题意 device problem
原文地址:https://www.cnblogs.com/Lanly/p/12121823.html