题意:
答案:125(闰年:是4的倍数且不是100的倍数,或者是400的倍数)
代码:
//解析明码
#include
using namespace std;
int main() {
int x, y;
for(int i = 0; i < 10; ++i) {
for(int j = 0; j < 16; ++j) {
cin >> x >> y;
bitset<8> b1(x); bitset<8> b2(y);
cout << b1 << b2 << endl;
}
}
return 0;
}
//求9的9次方
#include
using namespace std;
typedef long long LL;
int main() {
LL res = 9;
for(int i = 0; i < 8; ++i) {
res = res * 9;
}
cout << res << endl;
return 0;
}
答案:387420489
#include
using namespace std;
typedef long long LL;
int main() {
int x, two = 0, ten = 0;
for(int i = 0; i < 100; ++i) {
cin >> x;
while(x) {
if(x % 2 == 0) x /= 2, ++two;
else if(x % 5 == 0) x /= 5, ++ten;
else break;
}
}
cout << min(two, ten);
return 0;
}
答案:31
题意:
做法:没有想到这竟然是一道动态规划题,dp[i][k]代表当前最高i楼,并且有k部手机在最佳策略下最坏情况需要测试几次。转移方程如下: d p [ i ] [ k ] = m i n ( m a x ( d p [ i − j ] [ k ] , d p [ j − 1 ] [ k − 1 ] ) + 1 , d p [ i ] [ k ] ) ; dp[i][k] = min(max(dp[i-j][k], dp[j-1][k-1]) + 1, dp[i][k]); dp[i][k]=min(max(dp[i−j][k],dp[j−1][k−1])+1,dp[i][k]);
j代表的含义是当前正在测试j层,如果手机没碎,那么最坏情况下还需要测试i-j层,如果手机碎了,那么现在还剩下k-1部手机,且需要测试j-1层。
代码:
#include
using namespace std;
const int N = 1000;
const int Mod = 1e5;
int dp[N+10][4];
int main() {
memset(dp, 0x3f, sizeof dp);
for(int i = 0; i <= N; ++i) dp[i][1] = i;
for(int k = 2; k <= 3; ++k) {
dp[0][k] = 0;
for(int i = 1; i <= N; ++i) {
for(int j = 1; j <= i; ++j) {
dp[i][k] = min(max(dp[i-j][k], dp[j-1][k-1]) + 1, dp[i][k]);
}
}
}
cout << dp[N][3];
return 0;
}
答案: 19
答案:a , i+1 , r , k-(i+1-l)
题意:
做法:先对3个数组排序,再对于b数组,统计c数组中比bi大的有多少个,记录在sum数组里面,再对sum数组计算一遍前缀和,最后遍历一遍a数组,加上对应的sum数组。
代码:
#include
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int a[N], b[N], c[N];
LL sum[N];
int main() {
int n; scanf("%d", &n);
for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
for(int i = 0; i < n; ++i) scanf("%d", &b[i]);
for(int i = 0; i < n; ++i) scanf("%d", &c[i]);
sort(a, a+n); sort(b, b+n); sort(c, c+n);
int p1 = 0, p2 = 0, p3 = 0;
LL res = 0;
for(int i = 0; i < n; ++i) {
while(p3 < n && c[p3] <= b[i]) ++p3;
sum[i] = n - p3;
}
for(int i = n-2; i >= 0; --i) sum[i] += sum[i+1];
for(int i = 0; i < n; ++i) {
while(p2 < n && b[p2] <= a[i]) ++p2;
res += sum[p2];
}
printf("%lld\n", res);
return 0;
}
代码:
#include
using namespace std;
typedef long long LL;
int main() {
int x, y, c, qx, qy;
scanf("%d%d", &x, &y);
c = max(abs(x), abs(y));
LL res;
qx = -c; qy = qx+1; res = 4ll*c*(c-1)+1;
if(x <= 0) {
if(y <= 0) {
if(x == -c && y == qy-1) res += 8*c - 1;
else if(x == -c) res += y - qy;
else if(y == -c) res += 8*c-1-(x-qx);
} else {
if(x == -c) res += y - qy;
else if(y == c) res += c-qy+x-qx;
}
} else {
res += c-qy;
if(y >= 0) {
if(x == c) res += c-qx+c-y;
else if(y == c) res += x-qx;
} else {
res += 3*c;
if(x == c) res += -y;
else if(y == -c) res += c + (c-x);
}
}
printf("%lld\n", res);
return 0;
}
题意:
做法:根据id存储该id所在时间,然后根据每个id进行一次滑动窗口,一旦滑动窗口里的值大于等于k,就直接输出。
代码:
#include
using namespace std;
typedef long long LL;
const int N = 1e5+10;
vector<int> st[N];
int main() {
int n, d, k;
scanf("%d%d%d", &n, &d, &k);
for(int i = 0, ts, id; i < n; ++i) {
scanf("%d%d", &ts, &id);
st[id].push_back(ts);
}
for(int i = 0, l, len; i < N; ++i) {
if(st[i].size() == 0) continue;
sort(st[i].begin(), st[i].end());
len = st[i].size(); l = 0;
int sum = 0;
for(int r = 0; r < len; ++r) {
while(st[i][r]-st[i][l] >= d) ++l, --sum;
++sum;
if(sum >= k) {
printf("%d\n", i); break;
}
}
}
return 0;
}
做法:找到每个连通块(岛屿),并给每个岛屿标号,再遍历一遍标过号的vis,如果四周都没有0(海),那么这个岛屿必然不会完全沉没。
代码:
#include
using namespace std;
typedef long long LL;
const int ne[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
const int N = 1010;
char tu[N][N];
int vis[N][N], n;
void dfs(int x, int y, int k) {
vis[x][y] = k;
for(int i = 0, tx, ty; i < 4; ++i) {
tx = x + ne[i][0]; ty = y + ne[i][1];
if(tx < 1 || ty < 1 || tx > n || ty > n || vis[tx][ty] || tu[tx][ty] == '.') continue;
dfs(tx, ty, k);
}
}
int res[N*N];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%s", tu[i]+1);
int k = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
if(!vis[i][j] && tu[i][j] == '#') dfs(i, j, ++k);
}
}
/*for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) cout << vis[i][j] << " ";
cout << endl;
}*/
for(int i = 1, ti, tj; i <= n; ++i) for(int j = 1; j <= n; ++j) {
if(vis[i][j] && !res[vis[i][j]]) {
int f = 1;
for(int k = 0; k < 4; ++k) {
ti = i + ne[k][0]; tj = j + ne[k][1];
if(ti < 1 || tj < 1 || ti > n || tj > n) continue;
if(!vis[ti][tj]) {
f = 0; break;
}
}
if(f) res[vis[i][j]] = 1;
}
}
int ans = 0;
for(int i = 1; i <= k; ++i) {
if(!res[i]) ++ans;
}
printf("%d\n", ans);
return 0;
}
题意:
做法:问题很简单,就是选K个数相乘结果最大,有正有负有0,那么就得分情况讨论了。
代码:
#include
using namespace std;
typedef long long LL;
const LL INF = 1e15;
const int N = 1e5+10;
const LL Mod = 1e9+9;
int fs, n, k;
LL sum = 1, mid1, mid2, a[N];
void solve(int l, int r) { //k偶,有正有负有0
while(l < fs-1 || r > fs) {
mid1 = mid2 = -INF;
if(l + 1 < fs) mid1 = a[l] * a[l+1];
if(r - 1 >= fs) mid2 = a[r-1] * a[r];
if(mid1 > mid2) sum = mid1 % Mod * sum % Mod, l += 2;
else sum = mid2 % Mod * sum % Mod, r -= 2;
k -= 2;
if(!k) return;
}
sum = sum * a[l] % Mod * a[r] % Mod;
return ;
}
int main() {
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i) {
scanf("%lld", &a[i]);
if(a[i] < 0) ++fs;
}
sort(a, a+n);
if(k & 1) {
if(fs == 0 || fs == n) { //k奇全正或者全负 0
for(int i = n-1; i >= n-k; --i) sum = sum * a[i] % Mod;
} else { //有正有负k奇
sum = sum * a[n-1] % Mod; --k;
if(k) solve(0, n-2);
}
} else {
if(!fs) { //k偶全正 0
for(int i = n-1; i >= n-k; --i) sum = sum * a[i] % Mod;
} else if(fs == n) { //k偶全负
for(int i = 0; i < k; ++i) sum = sum * a[i] % Mod;
} else { //有正有负k偶
solve(0, n-1);
}
}
printf("%lld\n", sum);
return 0;
}