题目在牛客上有https://ac.nowcoder.com/acm/contest/625#question
C 六数学家的困惑
题意:就是给你两串数字,每次只能从其中一串数字的左侧或右侧取出一个数字,然后组成一串最大的字典序最大的串。做法是把两串数字翻转一下,变成四串数字,每次从字典序最大的那串数取数。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 5;
int main()
{
int n, Case = 0;
string a, b, t;
cin >> n;
while(n--){
cin >> a >> b;
cout << "Case #" << ++Case << ": ";
while(a.length() || b.length()){
t = a;
reverse(a.begin(), a.end());
a = max(a, t);
t = b;
reverse(b.begin(), b.end());
b = max(b, t);
if(a < b) swap(a, b);
cout << a[0];
a.erase(0, 1);
}
cout << endl;
}
return 0;
}
E 数独挑战
暴力搜索题,每次判断填的数在行列中和小九宫格中是否出现过。
#include <bits/stdc++.h>
using namespace std;
int num[9][9], flag;
int col[10][10], row[10][10];//列 行标记
int nine[3][3][10];
void print(){
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
cout << num[i][j];
if(j != 8) cout << " ";
}
cout << endl;
}
}
void dfs(int x, int y){
if(flag) return ;
if(y == 9){
flag = 1;
print();
return ;
}
if(num[y][x] == 0){
for(int i = 1; i <= 9; i++){
if(!col[x][i] && !row[y][i] && !nine[y / 3][x / 3][i]){
col[x][i] = 1;
row[y][i] = 1;
nine[y / 3][x / 3][i] = 1;
num[y][x] = i;
dfs((x + 1) % 9, y + (x + 1) / 9);
col[x][i] = 0;
row[y][i] = 0;
nine[y / 3][x / 3][i] = 0;
}
}
num[y][x] = 0;
}
else{
dfs((x + 1) % 9, y + (x + 1) / 9);
}
}
int main()
{
flag = 0;
memset(col, 0, sizeof(col));
memset(row, 0, sizeof(row));
memset(nine, 0, sizeof(nine));
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
cin >> num[i][j];
col[j][num[i][j]] = 1;
row[i][num[i][j]] = 1;
nine[i / 3][j / 3][num[i][j]] = 1;
}
}
dfs(0, 0);
return 0;
}
F 翻牌游戏
概率DP。但是可从后面的样例推出规律 2n-1
#include <cstdio>
int main() {
int t;
double n;
scanf("%d", &t);
while(t--){
scanf("%lf", &n);
printf("%.2lf\n", 2*n-1);
}
return 0;
}
H Parco_Love_GCD
先把n个数的公共gcd求出来。然后对每个子序列的起点往后求gcd,有和公共gcd相同的可用直接计算ans = (ans + (n - 1 - j) * com) % MOD然后跳过这轮循环。数据比较水,到后面有许多相同的数QAQ
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define MOD 1000000007
const int maxn = 5e5 + 5;
LL a[maxn];
LL gcd(LL a, LL b){
return b == 0 ? a : gcd(b, a % b);
}
int main() {
LL ans = 0, com, res, n;//com公共公约数
cin >> n;
for(int i = 0; i < n; i++){
cin >> a[i];
if(i == 0) com = a[i];
else com = gcd(a[i], com);
}
/*
16 4 7 21 3
res 16 4 1 1 1
*/
//cout << com << endl;
for(int i = 0; i < n; i++){
res = a[i];
for(int j = i; j < n; j++){
res = gcd(res, a[j]);
ans = (ans + res) % MOD;
if(res == com){//如果这里的公共公约数=com,那后面的公共公约数肯定也是com,直接加起来
ans = (ans + (n - 1 - j) * com) % MOD;
break;//后面不用计算了
}
}
}
cout << ans << endl;
return 0;
}
I 炒股
贪心题,每次加上两数差为正数
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 5;
int main()
{
std::ios::sync_with_stdio(false);
LL ans = 0, n, last, a;
cin >> n;
for(int i = 0; i < n; i++){
cin >> a;
if(i >= 1 && last < a) ans += a - last;
last = a;
}
cout << ans << endl;
return 0;
}
L 石头剪刀布
签到题
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
char a[10];
cin >> n;
while(n--){
cin >> a;
if(a[0] == 'S') cout << "Rock" << endl;
else if(a[0] == 'R') cout << "Paper" << endl;
else cout << "Scissors" << endl;
}
return 0;
}