A. Binarize It
题意
输入一个数n,输出第一个大于等于n的二的幂次数。
题解
打表后直接枚举
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll pow_2[100];
int main(){
pow_2[0] = 1;
for(int i = 1 ; i <= 30 ; i++)pow_2[i] = pow_2[i - 1] << 1;
int t;
cin >> t;
while(t--){
cout << "Input value: ";
int n;
cin >> n;
cout << n << "\n";
for(int i = 1 ;; i ++){
if(pow_2[i] >= n){
cout << pow_2[i] << "\n" << "\n";
break;
}
}
}
}
C. Tip to be Palindrome
题意
输入一个数n, 从1.2 * n(向上取整百度翻译了一个四舍五入直接暴毙,好好学英语 ) 开始寻找第一个回文数并输出
题解
直接枚举
#include<bits/stdc++.h>
using namespace std;
bool check(int n){
int x = n, h = 0;
while(x){
h = h * 10 + x % 10;
x /= 10;
}
return n == h;
}
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << "Input cost: " << n << "\n";
for(int i = (int)(0.2 * n + 0.999) ; ; i++){
if(check(n + i)){
cout << i << " " << i + n << "\n" << "\n";
break;
}
}
}
}
D. Soccer Standings
题意
给定n只球队以及k场比赛的结果, 比赛结果以(队名,进球数,队名,进球数)形式给出。
加分规则参照传统球赛
要求以积分,净胜球, 进球数, 队名字典序排序后输出
输出格式队名, 积分, 胜, 负, 平, 进球, 丢球
题解
结构体模拟//非常不仔细wa了两发,对不起队友quq
#include<bits/stdc++.h>
using namespace std;
struct hsh{
int w, l, p, j, x, d;//胜 负 平 积分 进球数 丢球数
string s;
};
hsh a[405];
bool cmp(hsh a, hsh b){
if(a.j != b.j)return a.j > b.j;
if(a.x - a.d != b.x - b.d)return a.x - a.d > b.x - b.d;
if(a.x != b.x)return a.x > b.x;
return a.s < b.s;
}
int main(){
int t;
cin >> t;
for(int tt = 1 ; tt <= t ; tt++){
cout << "Group " << tt << ":\n";
int n, m;
cin >> n >> m;
for(int i = 1 ; i <= n ; i++){
cin >> a[i].s;;
a[i].d = a[i].j = a[i].l = a[i].p = a[i].w = a[i].x = 0;
}
while(m--){
int x, y;
string s1, s2;
cin >> s1 >> x >> s2 >> y;
for(int i = 1 ; i <= n ; i++){
if(a[i].s == s1){
a[i].x += x;
a[i].d += y;
if(x > y){
a[i].w += 1;
a[i].j += 3;
}
else if(x < y){
a[i].l += 1;
}
else {
a[i].p += 1;
a[i].j += 1;
}
}
else if(a[i].s == s2){
a[i].x += y;
a[i].d += x;
if(x > y){
a[i].l += 1;
}
else if(x < y){
a[i].w += 1;
a[i].j += 3;
}
else {
a[i].p += 1;
a[i].j += 1;
}
}
}
}
sort(a + 1, a + 1 + n, cmp);
for(int i = 1 ; i <= n ; i++){
cout << a[i].s << " " << a[i].j << " " << a[i].w << " " << a[i].l << " " << a[i].p << " " << a[i].x << " " << a[i].d << "\n";
}
cout << "\n";
}
}
E. NIH Budget
题意
分组背包裸题,给定n组,每组四个。每组最多取一件物品,在不超过背包容量的情况下求物品价值和最大
题解
这题用深搜和dp都行
这里写一种dp解法
这题的主要坑点在每组四取一这里,为了保证四个物品之间互不影响必须控制一下dp时循环的顺序。
第一层枚举每个组,第二层枚举组中四件物品,第三层枚举背包容量
转移方程
背包容量小于物品重量时 dp[i][k] = max(dp[i][k], dp[i - 1][k])
大于等于时 dp[i][k] = max(dp[i - 1][k], max(dp[i][k], dp[i - 1][k - a[i].w[j]] + a[i].v[j]));
因为第i个背包中的物品都是从第i - 1的状态转移过来,所以组内物品之间不会互相影响
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct hsh{
int v[10], w[10];
}a[50];
int n, w;
ll dp[15][100005];
ll dpp[100005];
int main(){
int t;
cin >> t;
for(int tt = 1 ; tt <= t ; tt++){
cin >> n >> w;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= 4 ; j++)cin >> a[i].w[j] >> a[i].v[j];
}
memset(dp, 0, sizeof(dp));
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= 4 ; j++){
for(int k = 0 ; k < min(a[i].w[j], w) ; k++)dp[i][k] = max(dp[i][k], dp[i - 1][k]);
for(int k = a[i].w[j] ; k <= w ; k++){
dp[i][k] = max(dp[i - 1][k], max(dp[i][k], dp[i - 1][k - a[i].w[j]] + a[i].v[j]));
}
}
}
ll ans = 0;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= w ; j++)ans = max(ans, dp[i][j]);
}
printf("Budget #%d: Maximum of %lld lives saved.\n\n", tt, ans);
}
}
G. Plate Spinning
题意
给定开始速度为p的n个盘子,每秒转速减5,杂技师可不花费任何时间将一个盘子的转速提高到p,但在两个盘子间转移需要0.5 s的时间,询问能否保持所有盘子不掉落,其中对于速度刚到0的特殊情况视为可以进行加速
题解
无论以何种顺序加速,第一个再回到第一个至少都要间隔n * 0.5 s,因此p需要保证在这段时间内速度不降为0。这样提交就能开心的收获一发wa
还要特判一个 n = 1的特例,一定能保持住。题面不行
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
for(int tt = 1 ; tt <= t ; tt++){
cout << "Circus Act " << tt << ":\n";
int n, p;
cin >> n >> p;
if(5 * n <= p * 2 || n == 1){
cout << "Chester can do it!\n\n";
}
else cout << "Chester will fail!\n\n";
}
}
I. Pegasus Circle Shortcut
题意
以两种方法从点走到t点, 第一种是按圆弧,第二种是通过给定的n个点,沿着点于点的连线走(顺序不可更改),比较两者哪个距离更短
题解
第二种计算较为简单,仅需算n+1条线段和即可
第一种延弧线走法对精度要求极高阴间,使用asin函数求角度会被卡掉, 于是使用atan2函数相减求角,并按题目要求逆时针方向走,确定具体哪个角。据说直接按最小角算即可???
#include<bits/stdc++.h>
using namespace std;
#define PI (acos(-1))
#define eps (1e-12)
struct point{
double x, y;
};
point a[505];
bool check(point c, point s, point t){
return abs(c.x) < eps && abs(c.y) < eps && abs(s.x) < eps && abs(s.y) < eps && abs(t.x) < eps && abs(t.y) < eps;
}
double ju(point a, point b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main(){
for(int tt = 1; ; tt++){
point c, s, t;
cin >> c.x >> c.y >> s.x >> s.y >> t.x >> t.y;
if(check(c, s, t))break;
double r = ju(c, t);
double ans = atan2(t.y - c.y, t.x - c.x) - atan2(s.y - c.y, s.x - c.x), ans1 = 0;
while (ans < 0.0)
ans += 2 * PI;
while (ans > 2 * PI)
ans -= 2 * PI;
ans *= ju(s, c);
int n;
cin >> n;
a[0] = s;
a[n + 1] = t;
for(int i = 1 ; i <= n ; i++)cin >> a[i].x >> a[i].y;
for(int i = 0 ; i <= n ; i++){
ans1 += ju(a[i], a[i + 1]);
}
cout << "Case #" << tt << ": ";
if(ans > ans1)cout << "Watch out for squirrels!\n\n";
else cout << "Stick to the Circle.\n\n";
}
}