2025年寒假ACM训练赛1
A: 偶数和
现在有一个M行N列的二维整型数组,该数组中所有元素全为正整数。
请编写一个程序计算该二维数组中所有偶数之和。输入
单组输入。
第1行输入两个正整数M和N,M和N均不超过100,二者之间用一个英文空格隔开。
接下来M行,每行包含N个整数,整数的取值范围为[1, 1000],相邻两个数字之间用一个英文空格隔开。输出
输出该二维数组中所有偶数之和。
样例输入 Copy
3 3 1 2 3 4 5 6 3 2 1样例输出 Copy
14
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
void solve(){
int m,n;
cin>>m>>n;
int s=0;
for(int i=0;i<m*n;i++){
int x;
cin>>x;
if(x%2==0){
s+=x;
}
}
cout<<s<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
B: 再见卡路里
Kimi想通过爬楼梯来锻炼身体,消耗卡路里。通常越往上爬人越疲劳,速度越慢,消耗的卡路里越多(实际上涉及到的因素会更多)。
现在假设从1楼爬到2楼需消耗10卡的热量,从2楼爬到3楼需消耗11卡的热量,从3楼爬到4楼需消耗12卡的热量,以此类推,从第k楼爬到第k+1楼消耗(10+k-1)卡的热量。
现在Kimi想消耗N卡热量,则至少需要从1楼爬到几楼?输入
单组输入。
输入一个正整数N表示需要消耗的热量数量(单位:卡),10<=N<=2000。输出
输出一个正整数,表示消耗N卡热量需要从1楼开始爬到的最低楼层数。
样例输入 Copy
50样例输出 Copy
6
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
int a[2005];
int s[2005];
void solve(){
a[2]=10;
s[2]=10;
for(int i=3;i<=2000;i++){
a[i]=a[i-1]+1;
s[i]=s[i-1]+a[i];
}
int n;
cin>>n;
for(int i=2;i<=2000;i++){
if(n==s[i]){
cout<<i<<"\n";
return;
}
if(n>s[i]&&n<s[i+1]){
cout<<i+1<<"\n";
return;
}
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
C: HNUCM的直线跑道
HNUCM新修了一条长为N米的直线跑道,现在需要给这条跑道安装路灯。
已知M盏路灯的照射半径,请问至少需要多少盏路灯才能让跑道全部都被灯光覆盖?
注:全部都被灯光覆盖是指跑道上所有位置都能够至少被一盏路灯照到(不考虑跑道的宽度)。输入
单组输入。
第1行输入两个正整数N和M,分别表示直线跑道的长度(单位:米)和提供的路灯盏数,二者之间用一个英文空格隔开。(1<=N<=1000;1<=M<=200)
第2行输入M个正整数分别表示M盏路灯的照射半径,每盏灯的照射半径取值范围为[1, 10](单位:米),相邻两个正整数之间用一个英文空格隔开。输出
输出所需路灯的最少盏数;如果所有路灯都用上也不能让跑道全部被灯光覆盖则输出“No solution”。
样例输入 Copy
10 5 1 1 2 3 2样例输出 Copy
2
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
void solve(){
int m,n;
cin>>n>>m;
vector<int> a(m);
for(int i=0;i<m;i++){
cin>>a[i];
}
sort(a.begin(),a.end());
int s=0;
int t=0;
for(int i=m-1;i>=0;i--){
t++;
s=s+2*a[i];
if(s>=n){
cout<<t<<"\n";
return;
}
}
cout<<"No solution\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
D: 统计完全平方数
一个正整数a是一个完全平方数,是指它是某一个整数的平方,即存在一个整数b,使得a = b × b。
现在给你N个正整数,请编写一个程序统计其中包含多少个完全平方数?如果一个都没有则输出0。输入
单组输入。
第1行输入一个不超过100的正整数N表示输入的正整数个数。
第2行输入N个取值范围为[1,1000000]的正整数,相邻两个正整数之间用一个英文空格隔开。输出
输出这N个正整数中完全平方数的个数。
样例输入 Copy
12 2 4 6 8 10 9 7 5 3 1 2 3样例输出 Copy
3
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
void solve(){
int n;
cin>>n;
int s=0;
for(int i=0;i<n;i++){
int x;
cin>>x;
double xx=sqrt(x);
if(xx==(int)xx){
s++;
}
}
cout<<s<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
E: 四则运算
suzu现在有三个正整数a,b,c,suzu想知道在保证a,b,c顺序不改变的情况下,插入任意四则运算后所能得到的最大值,允许加括号,但是每个数字只能使用一次,且必须被使用一次。
输入
第一行输入三个正整数a,b,c。
1 ≤ a,b,c ≤ 100000
输出
输出一个整数,表示经过任意四则运算后可得到的最大值。
样例输入 Copy
1 3 2样例输出 Copy
8提示
(1 + 3) * 2 = 8
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 3e3+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
void solve(){
ll a,b,c;
cin>>a>>b>>c;
cout<<max({a+b+c,(a+b)*c,a*(b+c),a*b*c})<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
F: 黑夜过河问题
某夜,有N个人从河西要去往河东,他们发现只有一座独木桥连接河的两岸。
夜太黑,需要灯。灯仅一盏,最多供两人同时使用。
已知这N个人每人单独过独木桥所需时间(单位:分钟),如果两人一起过桥则总时间以单独过桥所需时间多者来计算。
记住:如果河西还有人,需要河东有人返回送灯。
请编写一个程序,计算这N个人全部顺利抵达河东所需要的最少时间(单位:分钟)。输入
单组输入。
第1行输入一个正整数N表示总人数,N不超过100。
第2行输入N个正整数,表示每个人单独过桥所需时间(单位:分钟)范围为[1, 20],相邻两个正整数之间用一个英文空格隔开。输出
输出N个人全部顺利过河所需至少时间(单位:分钟)。
样例输入 Copy
3 2 4 1样例输出 Copy
7
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
void solve(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a.begin(),a.end());
if(n==1){
cout<<a[0]<<"\n";
return;
}
int m1=0;
for(int i=1;i<n;i++){
m1+=a[i];
}
m1=m1+(n-2)*a[0];
for(int i=n-1;i>=1;){
if(a[i-1]+a[0]>a[1]*2){
m1-=a[i-1]+a[0];
m1+=a[1]*2;
i-=2;
}
else {
i--;
}
}
cout<<m1<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
G: 一九三四
2024年11月1日,湖南中医药大学迎来建校90周年华诞,学校举行了隆重的庆祝仪式。
1934年,于山河破碎的战火中,在中医废止的争论中,湖南中医药大学的前身湖南国医专科学校创建,誓要捍卫与复兴中医药事业。
现在给出一个由10个阿拉伯数字组成的数字方阵,请编写一个程序统计该数字方阵中所有的“1934”的个数。要求“1934”中四个数字要连续出现,方向可以是上、下、左、右中的任意一个。
例如在下面4*4的方阵中包含了两个“1934”:
1234
9340
3082
4432
分别是:
1234
9340
3082
4432
和
1234
9340
3082
4432输入
单组输入。
第1行为方阵的大小N(N<=30)。
第2行到第N+1行用于存储由阿拉伯数字组成的方阵,每一行包含N个阿拉伯数字。输出
输出方阵中包含的所有的“1934”的个数;如果一个都没有找到,则输出0。
样例输入 Copy
4 1234 9340 1234 9340样例输出 Copy
3
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e6+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
int n;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
char a[35][35];
bool b[35][35];
int sum;
string s = "1934";
void dfs(int x, int y, int t)
{
if (t == 4)
{
sum++;
return;
}
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 &&xx < n &&yy >= 0 &&yy < n && !b[xx][yy] && a[xx][yy] == s[t])
{
b[xx][yy] = true;
dfs(xx, yy, t + 1);
b[xx][yy] = false;
}
}
}
void solve(){
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (a[i][j] == '1')
{
memset(b, 0, sizeof(b));
b[i][j] = true;
dfs(i, j, 1);
}
cout << sum << "\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
H: 好想中彩票
为了丰富人民群众的生活、支持某些社会公益事业,北塔市设置了一项彩票。该彩票的规则是:
1.每张彩票上印有7个各不相同的号码,且这些号码的取值范围为 1∼33。
2.每次在兑奖前都会公布一个由七个各不相同的号码构成的中奖号码。
3.共设置7个奖项,特等奖和一等奖至六等奖。
兑奖规则如下:
特等奖:要求彩票上 7 个号码都出现在中奖号码中。
一等奖:要求彩票上有 6 个号码出现在中奖号码中。
二等奖:要求彩票上有 5 个号码出现在中奖号码中。
三等奖:要求彩票上有 4 个号码出现在中奖号码中。
四等奖:要求彩票上有 3 个号码出现在中奖号码中。
五等奖:要求彩票上有 2 个号码出现在中奖号码中。
六等奖:要求彩票上有 1 个号码出现在中奖号码中。
注:兑奖时并不考虑彩票上的号码和中奖号码中的各个号码出现的位置。例如,中奖号码为
23 31 1 14 19 17 18,则彩票12 8 9 23 1 16 7由于其中有两个号码(23和1)出现在中奖号码中,所
以该彩票中了五等奖。
现已知中奖号码和小明买的若干张彩票的号码,请你写一个程序帮助小明判断他买的彩票的中奖情况。输入
单组输入。
输入的第一行只有一个自然数 n(0<n<1000),表示小明买的彩票张数;
第二行存放了 7 个介于 1 和 33 之间的自然数,表示中奖号码;
在随后的 n 行中每行都有 7 个介于 1 和 33 之间的自然数,分别表示小明所买的 n 张彩票。输出
依次输出小明所买的彩票的中奖情况(中奖的张数),首先输出特等奖的中奖张数,然后依次输出一等奖至六等奖的中奖张数。
样例输入 Copy
2 23 31 1 14 19 17 18 12 8 9 23 1 16 7 11 7 10 21 2 9 31样例输出 Copy
0 0 0 0 0 1 1
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 3e3+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
int a[35],b[10];
void solve(){
int n;
cin>>n;
for(int i=0;i<7;i++){
int x;
cin>>x;
a[x]++;
}
while(n--){
int s=0;
for(int i=0;i<7;i++){
int x;
cin>>x;
if(a[x]){
s++;
}
}
b[s]++;
}
for(int i=7;i>0;i--){
cout<<b[i]<<" ";
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
I: 旋转
suzu有一个N行N列的网格,N是偶数。Ai, j 表示从上往下数第i行和从左往右数第j列的单元格。
每个单元格初始时都被染成黑色或白色。如果Ai, j = '#',表示这个单元格被染成了黑色,如果Ai, j = '.',则为白色。
现在suzu想对这个网格进行旋转操作。
他总共会进行N/2次操作。
对于第i次操作,suzu会找到在i和N + 1 - i之间的所有整数对(x,y)。然后将Ay,N + 1 - x的颜色替换为Ax,y的颜色。
注意,对于每一次操作,suzu会同时将所有的整数对(x,y)进行操作。
输入
第一行输入一个正整数N,2 ≤ N ≤ 3000, 且N是偶数。
第2~N + 1行,每行N个字符,保证只有.和#
输出
输出N行,每行N个字符。表示经过所有N / 2次操作之后的网格。
样例输入 Copy
8 .......# .......# .####..# .####..# .##....# .##....# .####### .#######样例输出 Copy
........ #######. #.....#. #.###.#. #.#...#. #.#####. #....... ########提示
.......# ........ ........ ........ ........ .......# ######.. #######. #######. #######. .####..# ######.. #....##. #.....#. #.....#. .####..# → ##..##.. → #....##. → #.##..#. → #.###.#. .##....# ##..##.. #..####. #.##..#. #.#...#. .##....# ##...... #..####. #.#####. #.#####. .####### ##...... #....... #....... #....... .####### ######## ######## ######## ########
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 3e3+10;
const int M = 1e9+7;
const int inf = 0x3fffffff;
const int P = 13331;
char a[N][N];
int n,t;
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
t=min(min(i,j),min(n+1-i,n+1-j));
t%=4;
if(!t){
cout<<a[i][j];
}
if(t==1){
cout<<a[n+1-j][i];
}
if(t==2){
cout<<a[n+1-i][n+1-j];
}
if(t==3){
cout<<a[j][n+1-i];
}
}
cout<<"\n";
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}