代码源每日一题Div2
101. 特殊的正方形
原题链接:特殊的正方形
思路:逐行输出,判断每个字符属于正方形的第几圈来决定输出‘+‘还是’.’
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(min(min(i, n - i + 1), min(j, n - j + 1)) % 2) cout << '+';
else cout << '.';
}
cout << endl;
}
return 0;
}
102. 走楼梯2
原题链接:走楼梯2
思路: 由于不能连续三次走两级楼梯,因此我们需要用一个二维数组dp[i][j]来表示走楼梯的状态,表示在走到第 j 级楼梯时连续走了 i 次两步,则状态转移方程为
dp[0][i] = dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1]
dp[1][i] = dp[0][i - 2]
dp[2][i] = dp[1][i - 2]
代码:
#include <bits/stdc++.h>
using namespace std;
long long n, dp[3][100];
int main(){
cin >> n;
dp[0][1] = 1, dp[1][2] = 1, dp[0][2] = 1;
for(int i = 3; i <= n; i++){
dp[0][i] = dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1];
dp[1][i] = dp[0][i - 2];
dp[2][i] = dp[1][i - 2];
}
cout << dp[0][n] + dp[1][n] + dp[2][n];
return 0;
}
103. 走路
原题链接:走路
思路:用step[i][j]表示第 i 步能否走到 j 的位置,设第 i 步可以向右走 a 或 b 的距离,则状态转移方程可写为
if(step[i - 1][j] = true) step[i][j + a] = true, step[i][j + b] = true
最后输出时根据step[n][]的bool值来判断能否走到相应的位置即可
代码:
#include <bits/stdc++.h>
using namespace std;
int n, m;
bool step[105][200005];
int main(){
cin >> n >> m;
step[0][0] = true;
for(int i = 1; i <= n; i++){
int a, b;
cin >> a >> b;
for(int j = 0; j <= m; j++){
if(step[i - 1][j]) step[i][j + a] = true, step[i][j + b] = true;
}
}
for(int i = 0; i <= m; i++){
if(step[n][i]) cout << '1';
else cout << '0';
}
return 0;
}
104. 简单分数统计
原题链接:简单分数统计
思路:每次输入题目时直接用for循环判断是否存在这个题目,如果存在且输入了 ’AC‘ 就给相应的提交者加分
代码:
#include <bits/stdc++.h>
using namespace std;
int n, m, k, qts[200];
string qtn[200];
struct stu{
string id;
int score = 0;
} s[200];
int main(){
cin >> n >> m >> k;
for(int i = 0; i < n; i++){
cin >> s[i].id;
}
for(int i = 0; i < m; i++){
cin >> qtn[i] >> qts[i];
}
for(int i = 0; i < k; i++){
string name, title, status;
cin >> name >> title >> status;
int indexx;
if(status == "AC"){
for(int j = 0; j < n; j++){
if(s[j].id == name){
indexx = j;
break;
}
}
for(int j = 0; j < m; j++){
if(qtn[j] == title){
s[indexx].score += qts[j];
break;
}
}
}
}
for(int i = 0; i < n; i++) cout << s[i].id << " " << s[i].score << endl;
return 0;
}
105. Alice的德州扑克
原题链接:Alice的德州扑克
思路:简单的模拟题,依次对牌型进行判断即可
代码:
#include <bits/stdc++.h>
using namespace std;
struct card{
int num, sty;
} c[5];
bool RFJudge(){
bool flag1 = false, flag2 = true;
if(c[0].num == 10 && c[1].num == 11 && c[2].num == 12 && c[3].num == 13 && c[4].num == 14) flag1 = true;
for(int i = 1; i < 5; i++){
if(c[i].sty != c[i - 1].sty) flag2 = false;
}
return (flag1 && flag2);
}
bool SFJudge(){
bool flag1 = true, flag2 = true;
for(int i = 1; i < 5; i++){
if(c[i].num != c[i - 1].num + 1) flag1 = false;
}
for(int i = 1; i < 5; i++){
if(c[i].sty != c[i - 1].sty) flag2 = false;
}
return (flag1 && flag2);
}
bool FOAKJudge(){
bool flag1 = true, flag2 = true;
for(int i = 0; i < 3; i++){
if(c[i].num != c[i + 1].num) flag1 = false;
}
for(int i = 1; i < 4; i++){
if(c[i].num != c[i + 1].num) flag2 = false;
}
return (flag1 || flag2);
}
bool FHJudge(){
bool flag1 = false, flag2 = false;
if(c[0].num == c[1].num && c[1].num == c[2].num && c[2].num != c[3].num && c[3].num == c[4].num && c[3].num == c[4].num) flag1 = true;
if(c[0].num == c[1].num && c[1].num != c[2].num && c[2].num == c[3].num && c[3].num == c[4].num && c[3].num == c[4].num) flag2 = true;
return (flag1 || flag2);
}
bool FJudge(){
bool flag1 = true;
for(int i = 0; i < 4; i++){
if(c[i].sty != c[i + 1].sty) flag1 = false;
}
return flag1;
}
bool SJudge(){
bool flag1 = true;
for(int i = 1; i < 5; i++){
if(c[i].num != c[i - 1].num + 1) flag1 = false;
}
return flag1;
}
int main(){
for(int i = 0; i < 5; i++) cin >> c[i].num;
for(int i = 0; i < 5; i++) cin >> c[i].sty;
if(RFJudge()) cout << "ROYAL FLUSH";
else if(SFJudge()) cout << "STRAIGHT FLUSH";
else if(FOAKJudge()) cout << "FOUR OF A KIND";
else if(FHJudge()) cout << "FULL HOUSE";
else if(FJudge()) cout << "FLUSH";
else if(SJudge()) cout << "STRAIGHT";
else cout << "FOLD";
return 0;
}
201. 任务分配
原题链接:任务分配
思路:简单的背包问题,用常规背包的思路即可解决
代码:
#include <bits/stdc++.h>
using namespace std;
int n, dp[1005][1005], maxt;
struct task{
int s, e, w;
} t[1005];
bool cmp(task a, task b){
return a.s < b.s;
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> t[i].s >> t[i].e >> t[i].w;
maxt = max(maxt, t[i].e);
}
sort(t + 1, t + n + 1, cmp);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= maxt; j++){
if(t[i].e > j) dp[i][j] = dp[i - 1][j];
else if(t[i].e == j) dp[i][j] = max(dp[i - 1][j], dp[i - 1][t[i].s] + t[i].w);
else dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
cout << dp[n][maxt];
return 0;
}
202. 路径计数
原题链接:路径计数
思路:动态规划, 设step[i][j]为走到(i, j)处的路径数,则状态转移方程为
step[i][j] += step[i - 1][j] + step[i][j - 1]
每次运算时记得用1e9 + 7对答案取模,避免数据溢出
代码:
#include <bits/stdc++.h>
using namespace std;
int n, step[105][105];
bool mp[105][105];
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> mp[i][j];
}
}
step[1][1] = 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(mp[i][j]) step[i][j] += (step[i - 1][j] + step[i][j - 1]) % int(1e9 + 7);
}
}
cout << step[n][n];
return 0;
}
203. 最大和上升子序列
原题链接:最大和上升子序列
思路:依次遍历序列a中所有元素,设dp[i]为第 i 个元素处的最大上升子序列和,则
dp[i] = max(dp[i], dp[i - 1] + a[i], dp[i - 2] + a[i], … , dp[1] + a[i]), 其中j > i - 1, j > i -2 , …
代码:
#include <bits/stdc++.h>
using namespace std;
int n, a[1005], dp[1005], ans;
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
dp[i] = a[i];
}
for(int i = 2; i <= n; i++){
for(int j = 1; j < i; j++){
if(a[i] > a[j]) dp[i] = max(dp[i], dp[j] + a[i]);
}
ans = max(ans, dp[i]);
}
cout << ans;
return 0;
}