H星人社交网络
题解
题目很简单,注意的是浮点数处理和相关的判断没写错就可以了,这种题目一般两种思路:
一个是前缀和,一个是取尺法
代码(前缀和)
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 1e6 + 5;
typedef long long LL;
int N;
LL A[MAXN], S[MAXN];
int main() {
while(~scanf("%d", &N)) {
memset(S, 0, sizeof(S));
for(int i = 0; i < N; i ++) {
scanf("%lld", &A[i]);
S[A[i]] ++;
}
for(int i = 1; i < MAXN; i ++) {
S[i] += S[i - 1];
}
LL ret = 0;
for(int i = 0; i < N; i ++) {
//printf("[[%d]]\n", i);
double l = A[i] / 8. + 8;
int lt = ceil(l);
int r = A[i] * 8 + 8;
if(A[i] < 88888 && r > 88888) r = 88888;
if(r >= lt)
ret += S[r] - S[lt - 1];
if(A[i] >= lt && A[i] <= r) ret --;
}
printf("%lld\n", ret);
}
return 0;
}
代码(取尺法)
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 1e6 + 5;
typedef long long LL;
int N;
LL A[MAXN];
int main() {
while(~scanf("%d", &N)) {
for(int i = 0; i < N; i ++) {
scanf("%lld", &A[i]);
}
sort(A, A + N);
int l = 0, r = -1;
LL ret = 0;
for(int i = 0;i < N;i ++){
while(l < N && A[l] * 8< A[i] + 64) l ++;
while(r < N && A[r] <= A[i] * 8 + 8 && (A[i] >= 88888 || A[i] < 88888 && A[r] <= 88888)) r++;
r --;
//printf("%d, %d\n", l, r);
if(r >= l) ret += r - l + 1;
if(i >= l && i <= r) ret --;
}
printf("%lld\n", ret);
}
return 0;
}
Jerry的奶酪
题解
这道题目涉及到了最短路,状态压缩和动态规划吧,状态压缩针对的对象很简单,就是针对K,因为范围在[0,10],去掉不必要的东西,将所有的奶酪建成一张图,然后再图上跑状压即可。
代码
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN = 3e2 + 5;
const int MAXM = 10 + 5;
const int INF = 0x3f3f3f3f;
typedef long long LL;
int N, M, K;
char MP[MAXN][MAXN];
int d[MAXM][MAXM];
bool vis[MAXN][MAXN];
int S[MAXM][1 << MAXM];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
vector<pair<int,int> > vp;
struct O{
int x;
union{
int y;
int bit;
};
int s;
O(int x, int y, int s):x(x), y(y), s(s){}
bool operator < (const O &p) const{
return bit > p.bit;
}
};
int bfs(int s, int t) {
memset(vis, false, sizeof(vis));
queue<O> Q;
while(!Q.empty()) Q.pop();
Q.push(O(vp[s].first, vp[s].second, 0));
vis[vp[s].first][vp[s].second] = true;
while(!Q.empty()) {
O p = Q.front();
Q.pop();
if(MP[p.x][p.y] == '1') return INF;
if(vp[t].first == p.x && vp[t].second == p.y) return p.s;
//if(x == N - 1 && y == M - 1) return;
for(int i = 0; i < 4; i ++) {
int nx = p.x + dx[i];
int ny = p.y + dy[i];
if(nx < 0 || nx >= N || ny < 0 || ny >= M || MP[nx][ny] == '1' || vis[nx][ny]) continue;
vis[nx][ny] = true;
Q.push(O(nx, ny, p.s + 1));
}
}
return INF;
}
void bfs2(int s, int t){
memset(S, 0x3f, sizeof(S));
priority_queue<O> Q;
while(!Q.empty()) Q.pop();
Q.push(O(s, 1 << s, 0));
S[s][1 << s] = 0;
while(!Q.empty()){
O p = Q.top();
Q.pop();
if(S[p.x][p.bit] < p.s) continue;
S[p.x][p.bit] = p.s;
for(int i = 0;i <= K + 1;i ++){
if(d[p.x][i] == INF || p.x == i) continue;
Q.push(O(i, p.bit | 1 << i, p.s + d[p.x][i]));
}
}
}
int main() {
while(~scanf("%d%d%d", &N, &M, &K)) {
for(int i = 0; i < N; i ++) {
scanf("%s", MP[i]);
}
int x, y;
int v = -1;
vp.clear();
for(int i = 0; i < K; i ++) {
scanf("%d%d", &x, &y);
MP[x][y] = v --;
vp.push_back(make_pair(x, y));
}
if(MP[0][0] != '1')MP[0][0] = v --;
if(MP[N - 1][M - 1] != '1')MP[N - 1][M - 1] = v --;
vp.push_back(make_pair(0, 0));
vp.push_back(make_pair(N - 1, M - 1));
memset(d, 0x3f, sizeof(d));
for(int i = 0; i < MAXM; i ++) d[i][i] = 0;
for(int i = 0; i < vp.size(); i ++) {
for(int j = 0;j < vp.size();j ++){
d[i][j] = d[j][i] = bfs(i, j);
}
}
bfs2(K, K + 1);
printf("%d\n", S[K + 1][(1 << K + 2) - 1] == INF ? -1 : S[K + 1][(1 << K + 2) - 1]);
}
return 0;
}
/*
5 5 3
01000
01010
00010
01010
00001
0 4
2 2
4 0
*/
数组分拆II
题解
贪心+动态规划
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 5;
const int mod = 1e9 + 7;
int b[MAXN];
int p[MAXN];
int l[MAXN], r[MAXN];
int N;
int A[MAXN];
int pre_p[MAXN];
LL S[MAXN];
LL f[MAXN];
int main() {
while(~scanf("%d", &N)) {
memset(pre_p, 0, sizeof(pre_p));
memset(b, 0, sizeof(b));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
memset(S, 0, sizeof(S));
for(int i = 1; i <= N; i ++) {
scanf("%d", &A[i]);
}
int l_p = 0;
for(int i = 1; i <= N; i ++) {
if(pre_p[A[i]] >= l_p) {
b[i] = b[i - 1] + 1;
l_p = i;
l[b[i]] = r[b[i]]= i;
r[b[i] - 1] = i - 1;
}
else b[i] = b[i - 1];
p[i] = max(p[i - 1], pre_p[A[i]]);
pre_p[A[i]] = i;
r[b[i]] = i;
}
f[0] = S[0] = 1;
for(int i = 1; i <= N; i ++) {
int t = max(p[i], l[b[i] - 1]) - 1;
LL tv = 0;
if(t >= 0) tv = S[t];
f[i] = ((S[min(i - 1, r[b[i] - 1])] - tv) % mod + mod) % mod;
S[i] = (S[i - 1] + f[i]) % mod;
}
printf("%d %lld\n", b[N], f[N] % mod);
}
return 0;
}