目录
A 距离和
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int main() {
int s=('L'-'A')+('N'-'L')+('Q'-'L')+('L'-'I')+('L'-'A')+('O'-'L')+('N'-'A')+('Q'-'A')+('I'-'A')+('O'-'A')+('Q'-'N')+('N'-'I')+('O'-'N')+('N'-'A')+('Q'-'I')+('Q'-'A')+('Q'-'O')+('I'-'A')+('O'-'I')+('O'-'A');
cout<<s;
return 0;
}
B 扩散
解析:
这道题有很多种方法(暴力、DFS、BFS)。博主只用BFS实现,提供暴搜的思路,代码留给读者去实现吧。
暴力:因为题目说2020分钟后,且一个黑方格往四周扩散一个单位,假如一个点(2020,2020)直向上扩散,2020min后扩散到(0,2020)。假如(2,2)向对角扩散,即扩散到(0,0),我们可以发现它的顺序是(2,2)->(2,1)->(1,1)->(0,1)->(0,0)(这是其中一种),需要4步。所以我们可以得到一条公式:已知一个点(a,b),它可以扩散到的点就是fabs((x-a)+(y-b))<=2020中的(x,y).利用这条公式循环即可。
BFS:直接套模板,详情见代码。
代码:
//BFS
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int sum,vis[10000][10000];//用vis存步长+标记
const int dr[]= {0,0,1,-1};
const int dc[]= {1,-1,0,0};
struct node {
int x,y;
node(int x=0, int y=0):x(x),y(y) {}
};
queue<node> q;
bool inside(int xx,int yy) {
if(xx>=10000 || xx<0 || yy>=10000 || yy<0) return false;
else return true;
}
void bfs() {
q.push(node(5000,5000));
q.push(node(7020,5011));
q.push(node(5011,5014));
q.push(node(7000,7000));
vis[5000][5000]=vis[7020][5011]=vis[5011][5014]=vis[7000][7000]=1;//这里是起点所以下面是2021
while(!q.empty()) {
node u=q.front();
q.pop();
if(vis[u.x][u.y]==2021) return;
for(int i=0; i<4; i++) {
int nx=u.x+dr[i];
int ny=u.y+dc[i];
if(inside(nx,ny) && !vis[nx][ny]) {//记得限界,不然死循环
vis[nx][ny]=vis[u.x][u.y]+1;
node v(nx,ny);
q.push(v);
}
}
}
}
int main() {
LL s=0;
bfs();
for(int i=1000; i<10000; i++)
for(int j=1000; j<10000; j++)
if(vis[i][j]>0) s++;
cout<<s;
return 0;
}
C 错误票据
解析:
这道题就是一道简单模拟题,不过它难在输入上。这个题的输入不是一个一个数输入,而是一行一行输入,有人就会说用字符串就好了,没错!就是字符串,由于它有空格,所以要用到getline,并且需要用getchar吃回车。
直到怎么输入字符串后,我们需要将这些字符串转成一个个数存到数组中,由于它是一行数,每个数间有空格,所以我们只能通过空格来存数进数组。
最后,我们排完序对比一下就能知道断号和重号了。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int a[10010],nn,s1,s2;
void fenjie(string ss) {
int res=0,n=0;
for(int i=0; i<ss.size() ; i++) {
if(ss[i]==' ') a[++nn]=res,res=0;
else res=res*10+(ss[i]-'0');
}
}
int main() {
int n;
cin>>n;
getchar();//吃回车
for(int i=0; i<n; i++) {//n行
string s;
getline(cin,s);//getline吃空格
s+=" ";//用空格来判定完整的一个数
fenjie(s);//将这一串串数字都转成int存入数组
}
sort(a+1,a+nn+1);//进行排序来找出错误票据
for(int i=1; i<nn; i++) {
if(a[i]==a[i+1]) s1=a[i];//重复
if(a[i]!=a[i+1] && a[i]+1!=a[i+1]) s2=a[i]+1;//错误
}
//for(int i=1; i<=nn; i++)
//if(a[i]>0) cout<<a[i]<<" ";
//cout<<endl;
cout<<s2<<" "<<s1;
return 0;
}
D 倍数问题
解析:
这道题在day5的时候做过(不过当时博主没做),当时没有写题解,比较忙,现在每天要有空都会写,唠完家常,接下来让我们分析一下题意。
这道题要我们求和为K的倍数且和为最大值,那么我们首先得取出3个数字使其和为K的倍数。大概思路:找出三个数 mod k相加后再mod k=0(本题难点),然后比较出最大值就行了,那么问题来了:这样岂不是要相加很多遍?这样时间复杂度高达10^15。当然不是全都取模然后再取模。题目说到和为最大,那我们只需要对其进行排序,然后取出其中三个最大值相加判定即可。具体实现和解释已经在代码中。
代码:
#include <bits/stdc++.h>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
vector<int> a[1005];//每个a[i]都是不定长数组(由于存入的数不知道有多少个,如果开a[1005][100000]就有点大了,浪费太多内存)
int n,k,maxn=0;
//从大到小排序
bool cmp1(int &a,int &b) {
return a>b;
}
int main() {
int x,sum;
cin>>n>>k;
for(int i=0; i<n; i++) {
cin>>x;
a[x%k].push_back(x);//用余数来存关系
}
for(int i=0; i<k; i++)
sort(a[i].begin(),a[i].end(),cmp1);//每堆都要排
/*for(int i=0; i<k; i++)
for(int j=0; j<a[i].size(); j++)
cout<<a[i][j]<<endl;*/
//选3个数且和为k的倍数,有几种选法(1,1,1),(3,0,0)=(0,0,3)=(0,3,0),(2,0,1)=(0,2,1),(0,1,2)=(2,1,0),(1,2,0)=(1,0,2)
for(int i=0; i<k; i++)
for(int j=0; j<k; j++) {
int h=(k-(i+j)%k) % k;
//这堆中需要有数才能取数,不然会出现系统赋值,或者系统无法读取到数值导致输出无效答案
if(a[h].size()&&a[j].size()&&a[i].size()) {
//三堆各选一个(1,1,1)
if(i!=h && i!=j && j!=h) {
sum=a[i][0]+a[j][0]+a[h][0];
maxn=max(maxn,sum);
}
//一堆中选三个(3,0,0)=(0,0,3)=(0,3,0)
if(i==j && j==h && a[i].size()>2) {
sum=a[i][0]+a[i][1]+a[i][2];
maxn=max(maxn,sum);
}
//有两堆相同,即一堆选两个,另一堆选一个(2,0,1)=(0,2,1)
if(i==j && i!=h && a[i].size()>1) {
sum=a[i][0]+a[i][1]+a[h][0];
maxn=max(maxn,sum);
}
//有两堆相同,即一堆选两个,另一堆选一个(0,1,2)=(2,1,0)
if(i==h && i!=j && a[i].size()>1) {
sum=a[i][0]+a[i][1]+a[j][0];
maxn=max(maxn,sum);
}
//有两堆相同,即一堆选两个,另一堆选一个(1,2,0)=(1,0,2)
if(h==j && i!=h && a[h].size()>1) {
sum=a[h][0]+a[h][1]+a[i][0];
maxn=max(maxn,sum);
}
}
}
cout<<maxn;
return 0;
}