2023/06/12刷题总结
A - Double Cola
如果n在1到5之间先单独判断是谁.
如果大于5之后,用一个cnt记录当前这一组由几个人排在一起,然后使用循环每次动态的删除人数,直到找到n在那一组,然后将剩下的n直接整除pow(2,cnt)就可以了.
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
signed main () {
string str[] = {"Sheldon", "Leonard", "Penny", "Rajesh", "Howard"};
int x;
cin >> x;
int cnt = 0;
if (x >= 1 && x <= 5) {//1--5的时候进行特判
cout << str[x - 1] << '\n';
return 0;
}
while (5 * pow(2, cnt) <= x) {//如果不在当前这个队的话
x -= 5 * pow(2, cnt);//减去这个队的人数
cnt++;//让重叠的人数加1
}
// cout<<x<<'\n';
// cout<<cnt<<'\n';
int id = x / (int)pow(2, cnt);//然后让剩下的人x除以pow(2,cnt),然后打印就可以了
// cout<<id<<'\n';
cout << str[id] << '\n';
return 0;
}
B - Fedor and New Game
直接判断a[1]--a[m]的前n位数字和a[m+1]的前n位数字不一样的数量,如果小于等于k的话计数器加1
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
int a[N];
signed main () {
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= m + 1; i++) {
cin >> a[i];
}
int ans = 0;
for (int i = 1; i <= m; i++) {
int num = 0;
for (int j = 0; j <= n; j++) {//判断前n位数
if (((a[i] >> j) & 1) != ((a[m + 1] >> j) & 1)) {//如果第i位数字不相同的话
num++;//num加1
}
}
if (num <= k) {//如果num<=k,ans加1
ans++;
}
}
cout << ans << '\n';
return 0;
}
C - Long Jumps
一个简单的DP问题.
需要从后面向前枚举.因为会从后面先前推导,所以先构建后面的.
最后打印答案
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 200008;
int dp[N];
int a[N];
void solve() {
int n;
scanf("%lld", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
for (int i = n; i >= 1; i--) {
dp[i] = a[i];//先在dp数组中放入当前的得分
if (i + a[i] > n) {//如果当前的分数已经超过的范围
continue;//继续
} else {//如果没有超过范围
int j = i + a[i];
dp[i] += dp[j];//找到dp[j]此时dp[j]一定是超出范围的,然后我们进行累加
}
}
int ans = 0;
for (int i = n; i >= 1; i--) {//找到最大的dp数组
ans = max(ans, dp[i]);
}
printf("%lld\n", ans);//打印
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
C - Frog Jumps
判断两个R之间的距离,然后取里面的最大值,最后打印里面的最大值,记得判断0号位置和n+1号位置.
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
void solve() {
string temp = "R";
string x;
cin >> x;
string s = temp + x;
int cnt = 0;
int mmax = -9999999999;
//将0号位置设置位R
for (int i = 0; i < (int)s.size(); i++) {
if (s[i] == 'R') {
mmax = max(i - cnt, mmax);//每次判断两个R之间的距离取较大值
cnt = i;
}
}
mmax = max((int)s.size() - cnt, mmax);//记得判断m+1个位置
cout << mmax << '\n';//打印mmax
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
B - Card Constructions
找到规律然后直接枚举棍的数量,直接从1e5开始枚举就可以
注意:有可能第i个可能会枚举多次记得判断.
最后打印数量
#include <bits/stdc++.h>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
typedef pair<int, int> PII;
const int N = 100008;
void solve() {
int n;
cin >> n;
int ans = 0;
for (int i = 1000000; i >= 1; i--) {
int num = (3 * i * (i - 1)) / 2 + 2 * i;//如果有i行需要的棍的数量
if (num > n) {//如果当前n不能构建i行的金字塔
continue;
} else {
ans++;//答案加1
n -= num; //减去相应的棍数
i++;//如果是这样的话继续判断当前能不能被再次判断
}
}
// while(n>=2){
// ans++;
// n-=2;
// }
cout << ans << '\n';
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
标签:总结,cout,int,long,ans,20230612,刷题,dp,define
From: https://www.cnblogs.com/harper886/p/17479009.html