做法:直接模拟就可。
代码:
#include
using namespace std;
int main() {
int mon = 200, res = 0;
for(int i = 1; i <= 100; ++i) {
mon -= 21; res += 11;
if(mon % 5 == 0) {
res += mon / 5; break;
}
}
cout << res;
return 0;
}
答案:74
做法:用的是二进制枚举判断(其实用dfs会更好),每次判断一下该情况是否合法。跑了半分钟左右。
代码:
#include
using namespace std;
typedef long long LL;
int main() {
int lst, x, f;
LL res = 0;
for(int i = 0; i < (1<<30); ++i) {
lst = -1; f = 1;
for(int j = 0; j < 30; ++j) {
x = ((i>>j)&1);
if(x == 1 && lst == 1) {
f = 0; break;
}
lst = x;
}
if(f) ++res;
}
cout << res;
return 0;
}
答案:2178309
题意:
做法:要知道a&-a可以计算到最右边的1,这个也是树状数组的核心所在,再向左挪一位再改变就可。
答案:a^((a&-a)*2)
——以下题目通过了 C语言网 的测试数据——
做法:任意一分钟到任意一分钟可以看成是0到任意分钟,那么问题转化成以最优策略从0到达n-1以内的数中执行两种操作(+1或者+k)最多是多少。所以bfs复杂度可过。
代码:
#include
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int N = 1e5+10;
int n, k, vis[N];
queue<pii> q;
int main() {
scanf("%d %d", &n, &k);
int s = 0, u, v, step, ans = 0;
vis[0] = 1; q.push(make_pair(0, 0));
while(!q.empty()) {
u = q.front().fi; step = q.front().se;
ans = max(ans, step);
q.pop();
v = (u + 1) % n;
if(!vis[v]) {
vis[v] = 1; q.push(make_pair(v, step+1));
}
v = (u + k) % n;
if(!vis[v]) {
vis[v] = 1; q.push(make_pair(v, step+1));
}
}
printf("%d\n", ans);
return 0;
}
做法:记忆化搜索,选择的积木是连续的,有三种情况,分别是升、先升后降、降,要搜索只限于这三种情况,所以得记录下来当前的趋势是在升还是在降。dp[i][j][k]代表第i列、上一列选了数字j、升(0)降(1)k,处理出每一列可以选的数字(low1数组),对记忆化搜索不熟悉呀,被某佬支配的恐惧(萌新瑟瑟发抖 )。
代码:
#include
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int N = 210;
const LL Mod = 1e9+7;
int n, m, low1[N];
char tu[N][N];
LL dp[N][N][2]; //第i列、上一个选了数字j、升(0)降(1)k
LL dfs(int i, int j, int k) {
if(i > m) return 1;
if(dp[i][j][k] != -1) return dp[i][j][k];
LL ans = 0;
for(int x = 0; x <= low1[i]; ++x) {
if(!k) {
if(x < j) ans += dfs(i+1, x, 1);
else ans += dfs(i+1, x, 0);
} else if(x <= j) ans += dfs(i+1, x, 1);
}
return dp[i][j][k] = ans % Mod;
}
int main() {
scanf("%d %d", &n, &m);
for(int j = 1; j <= m; ++j) low1[j] = n;
for(int i = 1; i <= n; ++i) {
scanf("%s", tu[i]+1);
for(int j = 1; j <= m; ++j) {
if(tu[i][j] == 'X') low1[j] = min(low1[j], n-i);
}
}
LL ans = 0;
memset(dp, -1, sizeof dp);
ans += dfs(0, 0, 0);
printf("%lld\n", ans % Mod);
return 0;
}
答案:
做法:貌似是莫比乌斯反演+欧拉函数?膜拜大佬