学习C++从娃娃抓起!记录下在学而思小猴编程学习过程中的题目,记录每一个瞬间。侵权即删,谢谢支持!
附上汇总贴:小猴编程C++ | 汇总-CSDN博客
【题目描述】
小猴热衷于卡牌游戏,今天他邀请朋友们来家里一起玩卡牌,卡牌背面有一个数字表示卡牌编号,卡牌正面也有一个数字表示点数。
游戏开始前,有
n
n
n 张卡牌背面朝上排成一排,编号从左到右依次为
1
∼
n
1\sim n
1∼n,第
i
i
i张卡牌的点数为
a
i
a_i
ai。
游戏开始之后,每个人选取两张卡牌(保证人数小于等于
n
/
2
n/2
n/2),游戏第一轮会淘汰一部分人,留下的人需要满足:选取的两张卡牌的点数互质。然后在留下的所有人决出胜者,留下的人中谁手中的两张卡牌背面的编号和最大,谁就是最终赢家。
小猴想要知道,最终赢家手中的两张卡牌的编号之和最大可能是多少,如果游戏第一轮把所有人都淘汰了,则输出
−
1
-1
−1。
【输入】
第一行,包含一个整数
T
T
T,表示包含
T
T
T组输入数据;
每组输入数据:
第一行,包含一个整数
n
n
n,表示卡牌数量。
第二行,包含
n
n
n 个整数
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an,第
i
i
i张牌的编号为
i
i
i,第
i
i
i张牌的点数为
a
i
a_i
ai。
【输出】
一行,一个整数,表示最终赢家手中的两张卡牌的编号之和的最大可能值。
【输入样例】
3
5
1 2 2 3 6
7
1 3 5 2 4 7 7
3
2 2 4
【输出样例】
7
12
-1
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int t, n, a[100005];
int f[2005];
int gcd(int x, int y)
{
while (x % y!=0) {
int r = x % y;
x = y;
y = r;
}
return y;
}
int main()
{
cin >> t;
while (t--) { // t次询问
memset(f, 0, sizeof(f)); // 每次询问要初始化下f数组
cin >> n; // 输入n
for (int i=1; i<=n; i++) { // 输入n个数
cin >> a[i]; // 输入n个牌的点数
f[a[i]] = i; // f数组用来存编号,如果多个排点数相同,记录后者即可(即编号更大的值)
}
int ans = -1;
for (int i=1; i<=2000; i++) { // 这里枚举点数,而不是枚举编号
for (int j=1; j<=2000; j++) {
if (f[i] && f[j] && gcd(i,j)==1) { // 如果i点数有牌,j点数有牌,且i和j互质
ans = max(ans, f[i]+f[j]); // 记录i和j点数的牌编号的最大值
}
}
}
cout << ans << endl; // 输出结果
}
return 0;
}
【运行结果】
3
5
1 2 2 3 6
7
7
1 3 5 2 4 7 7
12
3
2 2 4
-1