A. Div. 7
大致题意:给你一个整数n,你可以改变n的某一位,使得n没有前导0并且能够整除7,如果n本身就可以整除7,直接输出,否则输出改变后的最小的n。
题解:
如果n本身能够整除7,直接输出。
否则对于n的个位,从0~9循环列举,找到的一个能够整除n的数字即是答案。
代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
#define endl '\n'
using namespace std;
int main ()
{
ios :: sync_with_stdio(false);
int T; cin >> T;
for (int j = 1; j <= T; j ++ )
{
int n; cin >> n;
if (n % 7 == 0) cout << n << endl;
else{
n -= n % 10;
for (int i = 0; i <= 9; i ++ )
if ((n + i) % 7 == 0)
{
cout << n + i << endl;
break;
}
}
}
return 0;
}
B. Minority
大致题意:给定一个字符串s,都是由01组成。ss是s的一个连续的字串,比较ss中的01数目,去除最少的数目的数字,如果相等则输出0。
现求能够去除的最长的数字的个数
题解:
这道题非常简单,我们首先统计s中01各自出现的次数,
如果相同则输出0或者1的个数减一,
否则输出较少的那个
代码:
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <iomanip>
#define endl '\n'
using namespace std;
int main ()
{
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T; cin >> T;
while (T -- )
{
string s; cin >> s;
int num[2] = {};
for (int i = 0; i < s.length(); i ++ ) num[s[i] - 48] ++;
if (num[0] == num[1])
cout << num[0] - 1 << endl;
else
cout << min(num[0], num[1]) << endl;
}
return 0;
}
C. Kill the Monster
大致题意: 人血量hc,攻击力dc。怪兽血量hm,攻击力dm。
人先攻击怪兽,然后怪兽攻击人类,直至一方血量<=0。现在,人手里有k个硬币,每个硬币可以加攻击力w,血量a。
问:人最后是否能够在硬币的帮助下打败怪兽
题解: 首先假设人的血量和攻击力已经定下来,那么是否能够打败怪兽如何计算?
非常简单,分别计算人和怪兽能够承受的最大攻击次数,然后比较。由于人是先于怪兽攻击的,所以只要人的承受次数>=怪兽的承受次数就好了。
枚举每种硬币的使用情况然后判断;
代码:
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <iomanip>
#define endl '\n'
using namespace std;
int main ()
{
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T; cin >> T;
while (T -- )
{
string s; cin >> s;
int num[2] = {};
for (int i = 0; i < s.length(); i ++ ) num[s[i] - 48] ++;
if (num[0] == num[1])
cout << num[0] - 1 << endl;
else
cout << min(num[0], num[1]) << endl;
}
return 0;
}
D. Make Them Equal
大致题意: 给定一个长度为n 的数组a,初始值都是1。你可以对a数组的任意一项进行操作:a[i] = a[i] + a[i] / x;x是整数。
然后给定你长度同样为n 的数组b、c,如果a[i] == b[i],那么你将获得c[i]数目的硬币
问:在进行一些操作后,能够达到的硬币的最大数目是多少
题解: 首先得认清这个问题的本质:实际上就是一个非常简单的01背包问题,c[i]就是价值,将b[i]转化以后就是重量。就是在总次数不超过k的情况下,从n个元素中能够达到的最大价值。
我们用d[i]表示将1变到i所需要的次数;
代码:
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <iomanip>
#define endl '\n'
#define ll long long
using namespace std;
int main ()
{
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
const int N = 1e3 + 10;
vector <int> d(N, N);
d[1] = 0;
for (int i = 1; i < N; i ++ )//枚举a[i]
for (int x = 1; x <= i; x ++ )//枚举x
{
int j = i + i / x;
if (j < N) d[j] = min(d[j], d[i] + 1);
}//计算次数
int T; cin >> T;
while (T -- )
{
int n, k; cin >> n >> k;
vector <int> b(n + 10);
vector <int> c(n + 10);
int sum = 0;
for (int i = 1; i <= n; i ++ ) {cin >> b[i]; b[i] = d[b[i]]; sum += b[i];}
for (int i = 1; i <= n; i ++ ) cin >> c[i];
k = min(k, sum);//如果k非常大,则取小一点的情况
vector <int> f(k + 10, 0);
for (int i = 1; i <= n; i ++ )
for (int j = k; j >= b[i]; j -- )
f[j] = max(f[j], f[j - b[i]] + c[i]);
cout << f[k] << endl;
}
return 0;
}