A. A - Make It Zero
题意:
给你一个n个数字的数组,你可以执行至多八次操作,每次操作可以选取一个l和r,将l到r间的所有数替换为原来l到r之间数的总异或和。我们的目的是在操作后使数组所有数都变成0,可以证明一定有解决方案,且无需输出最小解决方案。
分析:
看到异或 0 ,突然一瞬间就来感觉,想起来自己和自己异或得0,于是直接想到把l取1,r取n,取第一次之后所有的数都是被同一个总异或和替换掉,取第二次l=1.r=n时把所有数异或到一起,然后直接开始爆写,写完直接交了个wa1哈哈哈,原来时我没考虑奇数,因为 偶数个相同的数异或到最后都是0,奇数个数相同的书异或到最后时多一个的,再考虑就觉得要先搞掉一个,留下偶数个的再用那个方法。好嘛,这就有思路了,我先把前两个数操作一遍,变成两个0,再把第二个数到最后一个(这时候就是偶数个了)按前面的方式再操作一遍,就ok啦,ac
代码:
#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int long long
#define endl '\n'
//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;
const int N1=2e6+10;
const int N2=2e4+10;
void solve()
{
int n;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(n%2==0)
{
cout<<2<<endl<<1<<' '<<n<<endl;
cout<<1<<' '<<n<<endl;
}
else
{
cout<<4<<endl<<1<<' '<<2<<endl;
cout<<1<<' '<<2<<endl;
cout<<2<<' '<<n<<endl;
cout<<2<<' '<<n<<endl;
}
}
signed main()
{
//师出彩笔
cin.tie(nullptr)->sync_with_stdio(0);
int turn=1;
cin>>turn;
while(turn--)
{
solve();
}
}
B. B - 2D Traveling
题意:
题目大概是说,一个人想用最低的机票价格从第A城旅行到第B城,题目输入告诉你总共有n个城,其中在前k个城市间飞行不需要钱,其他时候飞行则需要花费曼哈顿距离的钱(也就是x坐标的绝对差值和y坐标的绝对差值之和)
分析:
直接说我想到的正确的思路吧,因为免费城市之间是可以直接飞的,相当于传送,那么我们只需要找到距离a最近的免费城市和距离b最近的免费城市,比较这个最小的距离和 相对于ab间直接飞的距离,输出更小的那个即可
代码:
#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int long long
#define endl '\n'
//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;
void solve()
{
int n,k,a,b;
cin>>n>>k>>a>>b;
int x[n+1],y[n+1];
int amin=1e12,bmin=1e12;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
}
for(int i=1;i<=n;i++)
{
if(i<=k)
{
amin=min(amin,abs(x[i]-x[a])+abs(y[i]-y[a]));
bmin=min(bmin,abs(x[i]-x[b])+abs(y[i]-y[b]));
}
}
int zz=abs(x[a]-x[b])+abs(y[a]-y[b]);
cout<<min(zz,amin+bmin)<<endl;
}
signed main()
{
//师出彩笔
cin.tie(nullptr)->sync_with_stdio(0);
int turn=1;
cin>>turn;
while(turn--)
{
solve();
}
}
C. C - Fill in the Matrix
题意:
题目告诉我们n和m,需要我们构造一个矩阵,其中这个矩阵的每行都是0 - m-1的数的随机排列,对于每一列的数我们取他们的MEX(即最小的未出现的自然数),再对每列得到的MEX再合起来取个MEX,我们的目标是要使这个最后的MEX最大,我们需要输出最大MEX,再输出我们构造的矩阵
分析:
首先考虑几个特殊情况,当行数为1同时列数为1时,即1x1时,MEX为0,矩阵为0;当行数为1,列数大于1时,即1x几时,MEX为2,矩阵为一行的0 - m-1;当列数为1,行数大于1时,MEX为0,矩阵为一列的0 - m-1
再考虑其他情况,对于行数大于等于列数的可以这样考虑,最大MEX都为m,前m-1行都是有规律的变化,每次向前推一个顶到后面,后面多余的行都与第一行一样。
添加图片注释,不超过 140 字(可选)
对于行数小于列数的,最大MEX都为n+1,所有的行都是有规律的变化,每次向前推一个顶到后面
添加图片注释,不超过 140 字(可选)
关于证明有待读者自行发掘,思路历程有些复杂暂且不表
代码:
#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int long long
#define endl '\n'
//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;
void solve()
{
int n,m;
cin>>n>>m;
if(n==1&&m==1)
{
cout<<0<<endl<<0<<endl;
}
else if(n==1)
{
cout<<2<<endl;
for(int i=0;i<m;i++)
{
cout<<i<<' ';
}
cout<<endl;
}
else if(m==1)
{
cout<<0<<endl;
for(int i=0;i<n;i++)
{
cout<<0<<endl;
}
}
else if(n>=m)
{
int a[2*m];
for(int i=0;i<m;i++)
{
a[i]=i;
}
for(int i=m;i<2*m;i++)
{
a[i]=i-m;
}
cout<<m<<endl;
for(int i=0;i<n;i++)
{
if(i<m-1)
{
for(int j=0;j<m;j++)
{
cout<<a[j+i]<<' ';
}
cout<<endl;
}
else
{
for(int j=0;j<m;j++)
{
cout<<j<<' ';
}
cout<<endl;
}
}
}
else if(n<m)
{
cout<<n+1<<endl;
int a[2*m];
for(int i=0;i<m;i++)
{
a[i]=i;
}
for(int i=m;i<2*m;i++)
{
a[i]=i-m;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cout<<a[j+i]<<' ';
}
cout<<endl;
}
}
}
signed main()
{
//师出彩笔
cin.tie(nullptr)->sync_with_stdio(0);
int turn=1;
cin>>turn;
while(turn--)
{
solve();
}
}
CSDN:陪你一起cf
bilibili:acmer--沈幼楚
知乎:与你cf