目录
A:幸运数
解题思路
参考代码
B:有奖问答
解题思路
参考代码
C:平方差
解题思路
参考代码
D:更小的数
解题思路
参考代码
E:颜色平衡树
解题思路
参考代码
F:买瓜
解题思路
参考代码
G:网络稳定性
解题思路
参考代码
H:异或和之和
解题思路
参考代码
I:像素放置
解题思路
参考代码
J:翻转硬币
解题思路
参考代码
思路1:枚举1到100000000,跑的比较慢
思路2:因为是偶数,可以折半枚举,快多了,但是不能在1s内跑出来
思路3:动态规划,用表示前个数(包括)中,数位和为的数的个数,已经可以在1s内跑出来了
思路4:状态优化,用表示位数为的数中,数位和为的数的个数
参考代码1
#include
using namespace std;
bool cheak(int x) {
string s = to_string(x);
int len = s.size();
if (len % 2 == 1) return 0;
int s1 = 0, s2 = 0;
int l = 0, r = len - 1;
while (l < r) {
s1 += s[l] - '0';
s2 += s[r] - '0';
l++, r--;
}
if (s1 != s2) return 0;
return 1;
}
int cnt;
int main() {
for (int i = 1; i <= 100000000; i++) {
if (cheak(i)) cnt++;
}
cout << cnt;
return 0;
}
参考代码2
#include
using namespace std;
int sum[10000];
int s_num(int x) {
int s = 0;
while (x) {
s += x % 10;
x /= 10;
}
return s;
}
int cnt;
int main() {
for (int i = 1; i <= 9999; i++) sum[i] = s_num(i);
for (int k = 0; k <= 3; k++) {
for (int i = pow(10, k); i < pow(10, k + 1); i++) {
for (int j = 1; j < pow(10, k + 1); j++) {
if (sum[i] == sum[j]) cnt++;
}
}
}
cout << cnt;
return 0;
}
参考代码3
#include
using namespace std;
int sum[10000];
int f[50][10000];
int s_num(int x) {
int s = 0;
while (x) {
s += x % 10;
x /= 10;
}
return s;
}
int cnt;
int main() {
for (int i = 1; i <= 9999; i++) sum[i] = s_num(i);
for (int i = 1; i <= 9999; i++) {
for (int j = 1; j <= 36; j++) f[j][i] = f[j][i - 1];
f[sum[i]][i]++;
}
for (int k = 0; k <= 3; k++) {
int j = pow(10, k + 1) - 1;
for (int i = pow(10, k); i <= j; i++) {
cnt += f[sum[i]][j];
}
}
cout << cnt;
return 0;
}
参考代码4
#include
using namespace std;
int sum[10000];
int f[50][5];
int s_num(int x) {
int s = 0;
while (x) {
s += x % 10;
x /= 10;
}
return s;
}
int cnt;
int main() {
for (int i = 1; i <= 9999; i++) sum[i] = s_num(i);
for (int k = 0; k <= 3; k++) {
int j = pow(10, k + 1) - 1;
for (int i = 1; i <= 9 * (k + 1); i++) f[i][k + 1] += f[i][k];
for (int i = pow(10, k); i <= j; i++) {
f[sum[i]][k + 1]++;
}
}
for (int k = 0; k <= 3; k++) {
int j = pow(10, k + 1) - 1;
for (int i = pow(10, k); i <= j; i++) {
cnt += f[sum[i]][k + 1];
}
}
cout << cnt;
return 0;
}
思路1:暴力搜索,比较慢,得跑几秒才能有答案
思路2:动态规划,表示第次答题时,当前分数为的方案数,那么答案即为
参考代码1
#include
using namespace std;
int ans;
void dfs(int k, int sum) {
if (sum == 7) ans++;
if (k > 30 || sum == 10) return;
dfs(k + 1, 0);
dfs(k + 1, sum + 1);
}
int main() {
dfs(1, 0);
cout << ans;
return 0;
}
参考代码2
#include
using namespace std;
#define ll long long
ll f[50][15];
int main() {
f[0][0] = 1;
for (int i = 1; i <= 30; i++) {
for (int j = 0; j <= 9; j++) f[i][0] += f[i - 1][j];
for (int j = 1; j <= 10; j++) {
f[i][j] = f[i - 1][j - 1];
}
}
ll ans = 0;
for (int i = 1; i <= 30; i++) ans += f[i][7];
cout << ans;
return 0;
}
解题思路1:暴力枚举每个平方的差值,然后从左到右扫(40分)
解题思路2:暴力模拟发现,不满足的数符合,那么直接扫一遍,把不满足的数筛走即可,但是不能过极限数据()(100分)
解题思路3:因为有规律,其实只用找出两端不满足的数的下标,那么答案
解题思路4: 既是2的倍数但又不是4的倍数的数,那么不满足的个数为区间内2的倍数减去4的倍数,
参考代码1
#include
using namespace std;
#define ll long long
const int N = 1e7;
ll l, r;
bool is[N + 5];
void init() {
for (int i = sqrt(N); i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
is[i * i - j * j] = 1;
}
}
}
ll ans;
int main() {
init();
cin >> l >> r;
for (int i = l; i <= r; i++) {
if (is[i]) ans++;
}
cout << ans;
return 0;
}
参考代码2
#include
using namespace std;
#define ll long long
ll l, r;
ll ans;
int main() {
cin >> l >> r;
ans = r - l + 1;
for (int i = l; i <= r; i++) {
if ((i - 2) % 4 == 0) ans--;
}
cout << ans;
return 0;
}
参考代码3
#include
using namespace std;
#define ll long long
ll l, r;
ll ans;
int main() {
cin >> l >> r;
ans = r - l + 1;
int L, R;
for (int i = l; i <= r; i++) {
if ((i - 2) % 4 == 0) {
L = i;
break;
}
}
for (int i = r; i >= l; i--) {
if ((i - 2) % 4 == 0) {
R = i;
break;
}
}
ans -= (R - L) / 4 + 1;
cout << ans;
return 0;
}
参考代码4
#include
using namespace std;
#define ll long long
ll l, r;
ll ans;
int main() {
cin >> l >> r;
ans = (r / 2 - (l - 1) / 2) - (r / 4 - (l - 1) / 4);
cout << r - l + 1 - ans;
return 0;
}
解题思路1:直接枚举每一种方法(100分)
参考代码1
#include
using namespace std;
int n;
string s;
int ans;
int main() {
cin >> s;
n = s.size();
s = ' ' + s;
for (int l = 1; l + 1 <= n; l++) {
for (int r = l + 1; r <= n; r++) {
for (int k = 1; k <= (r - l + 1) / 2; k++) {
if (s[r - k + 1] < s[l + k - 1]) {
ans++;
break;
} else if (s[r - k + 1] > s[l + k - 1]) break;
}
}
}
cout << ans;
return 0;
}
解题思路1:直接暴搜(20分)
解题思路2:暴搜+玄学剪枝(60分)
解题思路3:折半搜索 (60分)
解题思路4:暴搜+玄学排序剪枝(100昏)(洛谷上过了)
参考代码1
#include
using namespace std;
#define ll long long
const int N = 1e2 + 5;
ll n, m;
ll a[N];
int ans = 999;
void dfs(int pre, int k, int sum) {
if (sum == m) {
ans = min(k, ans);
return;
}
for (int i = pre + 1; i <= n; i++) {
dfs(i, k, sum + a[i]);
dfs(i, k + 1, sum + a[i] / 2);
}
}
int main() {
cin >> n >> m;
m *= 2;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] *= 2;
}
dfs(0, 0, 0);
if (ans != 999) cout << ans;
else cout << -1;
return 0;
}
参考代码2
#include
using namespace std;
#define ll long long
const int N = 1e2 + 5;
ll n, m;
ll a[N], s[N];
int ans = 999;
void dfs(int pre, int k, int sum) {
if (k > ans || sum > m || sum + (s[n] - s[pre]) < m) return;
if (sum == m) {
ans = min(k, ans);
return;
}
for (int i = pre + 1; i <= n; i++) {
dfs(i, k, sum + a[i]);
dfs(i, k + 1, sum + a[i] / 2);
}
}
int main() {
cin >> n >> m;
m *= 2;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] *= 2;
s[i] = s[i - 1] + a[i];
}
dfs(0, 0, 0);
if (ans != 999) cout << ans;
else cout << -1;
return 0;
}
参考代码3
#include
using namespace std;
#define ll long long
const int N = 1e2 + 5;
ll n, m;
ll a[N];
int ans = 999;
struct node {
int val, cnt;
friend bool operator < (node a, node b) {
return 1;
}
};
sets1, s2;
void dfs(int k, int sum, int l, int r, set&st) {
if (sum > m) return;
st.insert({sum, k});
for (int i = l + 1; i <= r; i++) {
dfs( k, sum + a[i], i, r, st);
dfs( k + 1, sum + a[i] / 2, i, r, st);
}
}
int main() {
cin >> n >> m;
m *= 2;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] *= 2;
}
dfs(0, 0, 0, n / 2, s1);
dfs(0, 0, n / 2, n, s2);
for (auto i : s1) {
for (auto j : s2) {
if (i.val + j.val == m) ans = min(ans, i.cnt + j.cnt);
}
}
if (ans != 999) cout << ans;
else cout << -1;
return 0;
}
参考代码4
#include
using namespace std;
#define ll long long
const int N = 1e2 + 5;
ll n, m;
ll a[N], s[N];
int ans = 999;
void dfs(int pre, int k, int sum) {
if (k > ans || sum > m || sum + (s[n] - s[pre]) < m) return;
if (sum == m) {
ans = k;
return;
}
for (int i = pre + 1; i <= n; i++) {
dfs(i, k, sum + a[i]);
dfs(i, k + 1, sum + a[i] / 2);
}
}
bool cmp(int a, int b) {
return a > b;
}
int main() {
cin >> n >> m;
m *= 2;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] *= 2;
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + a[i];
}
dfs(0, 0, 0);
if (ans != 999) cout << ans;
else cout << -1;
return 0;
}
解题思路1:暴力枚举每一个区间,(60分)
解题思路2:
参考代码1
#include
using namespace std;
#define ll long long
const int N = 1e5 + 5;
ll n, x;
ll a[N];
ll sum;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) {
x = 0;
for (int j = i; j <= n; j++) {
x ^= a[j];
sum += x;
}
}
cout << sum;
return 0;
}
参考代码2