挑战赛#12题解
2024-11-26 18:17:17
发布于:广东
题解来了!!!
很可惜,这次只有五道题的题解,有道没做出来 : ( 没做出来的那道我也会发非AC题解。
T1:
一看就知道是累加再模。这题没有特别要注意的,唯一要注意的是不能所有的都先累加,会爆。要加一次就模一次。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long x,sum = 0;
cin >> x;
for(int i = 0;i < 5;i ++){
long long z;
cin >> z;
sum = (sum + z % x) % x;//优化
}
if(sum > 0) cout << sum;
else cout << x;
return 0;
}
T2:
这题在深入分析之后,会发现,只要是这两个水桶最大公因数的倍数,都可以量出来。同时,由于称重重量等于两个容器中剂量的总和,c不能大于a + b的和。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n;
cin >> n;
for(int i = 0;i < n;i ++){
long long a,b,c;
cin >> a >> b >> c;
long long g = __gcd(a,b);//最大公因数
if(c % g == 0 and a + b >= c){//不能比和还大
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
return 0;
}
T3:
这题看题意就已经简单明了了,就是一个纯纯的三维广搜,直接上代码:
#include<bits/stdc++.h>
using namespace std;
int dx[6] = {1,-1,0,0,0,0},dy[6] = {0,0,1,-1,0,0},dz[6] = {0,0,0,0,1,-1};
struct node{
int x,y,z,step;
};
int main(){
int _;
cin >> _;
while(_--){
int n,m,o,z;
cin >> o >> n >> m >> z;
int vis[55][55][55] = {};
int mp[55][55][55] = {};
for(int k = 0;k < o;k ++){
for(int i = 0;i < n;i ++){
for(int j = 0;j < m;j ++){
cin >> vis[k][i][j];
}
}
}
queue<node> q;
q.push({0,0,0,0});
vis[0][0][0] = 1;
bool flag = 0;
while(!q.empty()){
int ix = q.front().x,iy = q.front().y,iz = q.front().z,istep = q.front().step;
q.pop();
if(ix == n - 1 and iy == m - 1 and iz == o - 1){
if(istep > z){
cout << -1 << endl;
} else {
cout << istep << endl;
}
flag = 1;
break;
}
for(int i = 0;i < 6;i ++){
int nx = ix + dx[i],ny = iy + dy[i],nz = iz + dz[i];
if(vis[nz][nx][ny] == 0 and mp[nz][nx][ny] == 0 and nx >= 0 and ny >= 0 and nz >= 0 and nx < n and ny < m and nz < o){
vis[nz][nx][ny] = 1;
q.push({nx,ny,nz,istep + 1});
}
}
}
if(flag == 0){
cout << -1 << endl;
}
}
return 0;
}
T3:
别看这题分高,实际上手残党狂喜。暴力枚举是大部分新手的选择(结果被大数据制裁了)。正解是用数学方法。
就以2024后面的0为例:
5的倍数:floor(2024/ 5) = 404
25的倍数:floor(404/ 5) = 80
125的倍数:floor(80/ 5) = 16
625的倍数:floor(16/ 5) = 3
404 + 80 + 16 + 3 = 503
所以,2024后面有503个0。代码也就很简单了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int m;
cin >> m;
int n = 1,sum = 0;
vector<int> ans;
while(sum <= m){
sum = 0;
int tmp = n;
while(tmp){
sum += tmp /= 5;//每次都枚举5的倍数
}
if(sum == m){
ans.push_back(n);
}
n ++;
}
cout << ans.size() << endl;
for(int i = 0;i < ans.size();i ++){
cout << ans[i] << " ";
}
return 0;
}
T5:
这题没有过,写了个暴枚骗了点分。
非AC代码:
#include<bits/stdc++.h>
using namespace std;
map<string,bool> vis;
string str[50004];
int main(){
int n;
cin >> n;
for(int i = 0;i < n;i ++){
cin >> str[i];
vis[str[i]] = 1;
}
long long ans = 0;
for(int i = 0;i < n;i ++){
for(int j = i + 1;j < n;j ++){//尝试剪枝,没点卵用
string a = str[i];
string b = str[j];
swap(a[0],b[0]);
swap(a[a.size() - 1],b[b.size() - 1]);
if(vis[a] != 1 and vis[b] != 1) ans += 2;
}
}
cout << ans;
return 0;
}
T6:
这题就是典型的达标找规律,经过暴力出奇迹,我们会发现相同方向两个相邻的虚像相隔L+R,有了这个关系就很好推了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long t,l,r;
cin >> t >> l >> r;
while(t --){
char key;
long long x;
cin >> key >> x;
long long tmp = x / 2;
long long Xmod = x % 2;
long long ans = tmp * 2 * (l + r);//打表成果
if(key == 'L'){
ans += Xmod * 2 * l;//可能有单独的,加上去
} else {
ans += Xmod * 2 * r;
}
cout << ans << endl;
}
return 0;
}
如果这个题解对你有用,还请点个赞支持一下。
全部评论 1
In regards to T1, 记得把输入的 也取模。这样更保险点。虽然在本次测试点中没有卡掉这一个做法,但是在严格的测试点下这样子的做法没有办法拿到满分。
1周前 来自 美国
3谢谢指正!
1周前 来自 广东
0
有帮助,赞一个