欢乐赛#37非官方全题解
2025-01-06 19:30:32
发布于:北京
一、高精度乘法
题目
太简单了。但为了防止报各种奇奇怪怪的错,我们可以先算好,再输出一个常量。作者第一次写成int类型,WA了。
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
int n;
int main (int argc, const char * argv[])
{
//main;
while (T --)
{
//main;
cout << 219845122340 << endl;
}return 0;
}
码风有点奇怪,谅解一下。
正经的只有这一点···
#include <bits/stdc++.h>
using namespace std;
int main ()
{
//main;
cout << 219845122340 <<endl;
return 0;
}
二、数位之和的奇偶
题目
为了方便,我们用string类型。如下:
string s;
cin >> s;
数位分离,求和:
int _sum (string s)
{
int len = (int) s.length (), sum = 0;
for (int i = 0; i < len; i ++) sum += s[i];
return sum;
}
用函数代码整洁一点。
加判断:
if (_sum (to_string (n)) % 2 != 0) cout << "YES" << endl;
else cout << "NO" << endl;
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
int n;
int _sum (string s)
{
int len = (int) s.length (), sum = 0;
for (int i = 0; i < len; i ++) sum += s[i];
return sum;
}int main (int argc, const char * argv[])
{
//main;
cin >> T;
while (T --)
{
//main;
cin >> n;
if (_sum (to_string (n)) % 2 != 0) cout << "YES" << endl;
else cout << "NO" << endl;
}return 0;
}
三、最小公倍数
题目
概念说一下:
1、<n和m的最大公因数>:n和m的因数中,公共的、最大的数。一般记录为gcd (n, m)。
2、<n和m的最小公倍数>:n和m的倍数中,公共的、最小的数。一般记录为lcm (n, m)。
了解概念之后,就好办了。
算大公因时,我们用辗转相除法(欧几里德算法):
int gcd (int x, int y)
{
if (y == 0) return x;
return gcd (y, x % y);
}
算小公倍时,我们用n和m的积除以它们的大公因:
int lcm (int x, int y)
{
return x * y / gcd (x, y);
}
加上输入输出、调用:
cin >> n >> m;
cout << lcm (n, m) << endl;
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
int n, m;
int gcd (int x, int y)
{
if (y == 0) return x;
return gcd (y, x % y);
}int lcm (int x, int y)
{
return x * y / gcd (x, y);
}int main (int argc, const char * argv[])
{
//main;
//cin >> T;
while (T --)
{
//main;
cin >> n >> m;
cout << lcm (n, m) << endl;
}return 0;
}
四、回文串
题目
先写一个函数,用来翻转一个字符串s:
string s__s (string s)
{
string _s = s;
int len = (int) s.length ();
for (int i = 0; i < len; i ++)
{
_s[i] = s[len - i - 1];
}return _s;
}
因为系统函数叫啥我忘了。
然后把原串和反转后的字符串一起输出:
cout << s << s__s (s) << endl;
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
string s;
string s__s (string s)
{
string _s = s;
int len = (int) s.length ();
for (int i = 0; i < len; i ++)
{
_s[i] = s[len - i - 1];
}return _s;
}
int main (int argc, const char * argv[])
{
//main;
//cin >> T;
while (T --)
{
//main;
cin >> s;
cout << s << s__s (s) << endl;
}return 0;
}
五、中间的数
题目
看似很难,实则一点都不简单。作者第一时间想到的是偷分。应该是一道找规律的题。
先来看看样例组:
排序前 | 排序后 |
---|---|
2 1 3 | 1 2 3 |
1 2 | 1 2 |
很明显,这两组数据中所有的数都不一样,都只需要1次。自己再造几组样例后,就不难发现:当所有数都不一样时,只需要一次。因此,我们得到一份20分的抽象小代码:
sort (a + 1, a + n + 1, cmp);
for (int i = 1; i < n; i ++)
{
for (a [i - 1] != a[i]) return 0;
}cout << 1 << endl;
注意,这只是一次的,根据题目要求,共有T次。
题目中说要“向上取整”。自己再造几组普通样例后,可以发现:只需要将向上取整后的中间值项(排序后)后面所有与该项相同的数加1,就可以改变中间值。
所以,只需要求出从中间数开始数,一共有几个和它一样的即可,这就是答案。
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
#define true 1
#define false 0
using namespace std;
const int N = 1e3 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
int n, a[N];
bool cmp (int x, int y)
{
return x < y;
}int main (int argc, const char * argv[])
{
//main;
cin >> T;
while (T --)
{
//main;
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
sort (a + 1, a + n + 1, cmp);
int idx = (n + 1) / 2, cnt = 0;
for (int i = idx; i <= n; i ++)
{
if (a[i] == a[idx]) cnt ++;
}cout << cnt << endl;
}return 0;
}
注意“idx”是一个索引(下标),在“if”这里要指明是a数组中的第idx项。作者只写了idx,WA了。
六、开关灯游戏
题目
直接模拟就行。
先建一个二维数组,考虑到只有开和关两种情况,bool就行了。
注意题目中说“游戏开始时,所有灯都处于开启状态。”
bool nw[N][M] = {
{true, true, true},
{true, true, true},
{true, true, true}
};
再建一个int类型的,用来记录按了几次。
int n, m, a[N][M];
注意:“N”和“M”时前面定义好的常量。
不要钱的输入:(考虑到本来就是3 * 3的九宫格,为了写的顺手,定义了n和m)
n = 3; m = 3;
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++)
{
cin >> a[i][j];
}
}
写一个函数,用来操作开关灯。
void take_new (int x, int y)
{
for (int i = 0; i < 4; i ++)
{
int _x = x + dx[i], _y = y + dy[i];
nw[_x][_y] = !nw[_x][_y];
}nw[x][y] = !nw[x][y];
}
作者容易忘记写越界判断函数,RE了。
bool pd (int x, int y)
{
return (x < n && x > -1) && (y < m && y > -1);
}
最后注意输出格式,没有空格。作者加空格,WA了。
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++) cout << nw[i][j];
cout << endl;
}
Code:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#define endl "\n"
#define Ll long long
#define true 1
#define false 0
using namespace std;
const int N = 1e2 + 10, M = 1e2 + 10;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
Ll T = 1;
int n, m, a[N][M];
bool nw[N][M] = {
{true, true, true},
{true, true, true},
{true, true, true}
};
bool pd (int x, int y)
{
return (x < n && x > -1) && (y < m && y > -1);
}void take_new (int x, int y)
{
for (int i = 0; i < 4; i ++)
{
int _x = x + dx[i], _y = y + dy[i];
if (pd (_x, _y)) nw[_x][_y] = !nw[_x][_y];
}nw[x][y] = !nw[x][y];
}int main (int argc, const char * argv[])
{
//main;
//cin >> T;
while (T --)
{
//main;
n = 3; m = 3;
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++) cin >> a[i][j];
}for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++)
{
for (int k = 0; k < a[i][j]; k ++) take_new (i, j);
}
}for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++) cout << nw[i][j];
cout << endl;
}
}return 0;
}
给个周边吧······
这里空空如也
有帮助,赞一个