第一题 wireless 枚举即可,如果数据变大可用部分和优化
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int maxn = 600;
int d, n,w[maxn][maxn],x,y,z;
int cnt = 0, ans = 0;
int get(int x, int y)
{
int sum = 0;
for(int i = x-d; i <= x+d; ++i)
for(int j = y-d; j <= y+d; ++j)
if (i >=0 && j >=0)
sum += w[i][j];
return sum;
}
int main() {
freopen("wireless.in", "r", stdin);
freopen("wireless.out", "w", stdout);
scanf("%d%d", &d, &n);
for(int i = 1; i <= n; i++){
cin>>x>>y>>z;
w[x][y] = z;
}
for(int i = 0; i <= 128; i++)
for(int j = 0; j <= 128; j++) {
int x = get(i, j);
if(x > ans) {
ans = x;
cnt = 1;
} else if(x == ans)
cnt++;
}
printf("%d %d\n", cnt, ans);
return 0;
}
第二题:寻找道路,这道题感觉和NOIP2008的最优贸易类似,求最短路,只不过多了一点限制,那么我们先把满足要求的点找出来,在满足要求的点的新图上求个最短路即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include<queue>
using namespace std;
#define maxn 600000
struct Edge {
int v,next;
}e[maxn];
int first[maxn],d[maxn],u1[maxn], u2[maxn],en;
bool mark[maxn];
int n, m;
int s, t;
void add(int u, int v) {
en++;
e[en].v = v;
e[en].next = first[u];
first[u] = en;
}
void bfs(int u, int flag) {
memset(d, -1, sizeof(d));
queue<int> q;
q.push(u);
d[u] = 0;
while(!q.empty()) {
int x = q.front();
q.pop();
for(int j = first[x]; j > 0; j = e[j].next)
if (j % 2 == flag && !mark[e[j].v]) {
int v = e[j].v;
if(d[v] == -1) {
d[v] = d[x] + 1;
q.push(v);
}
}
}
return ;
}
int main() {
freopen("road.in", "r", stdin);
freopen("road.out", "w", stdout);
memset(first, -1, sizeof(first));
scanf("%d%d", &n, &m);
en = 0;
for(int i = 1; i <= m; i++) {
scanf("%d%d", &u1[i], &u2[i]);
add(u1[i],u2[i]);
add(u2[i],u1[i]);
}
scanf("%d%d", &s, &t);
bfs(t, 0);
for(int i = 1; i <= m; i++)
if(d[u2[i]] == -1)
mark[u1[i]] = true;
bfs(s, 1);
printf("%d\n", d[t]);
return 0;
}
f(x) = anx^n +...+a0
如果f(x) mod p = 0 x非常有可能是解,这样就不用写高精度了,70分
然后f(x) mod p != 0 那么f(x + Np) = f(x) != 0 那么实际上我们没有必要枚举1~M 因为我们可以枚举0~P-1,然后推测出p~M这些数哪些一定不是答案。
多找几个p把不是答案的剔除,剩下的基本上就是解了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define maxn 1000010
const int prime[] = {10007,10917,30071};
int n,m;
long long a[110][5];
bool f[100000][5];
int cnt[maxn];
char s[10010];
bool calc(int value, int j) {
long long tmp = 0;
for (int i = n; i>=0; --i)
tmp = (tmp * value + a[i][j]) % prime[j];
return tmp != 0;
}
int main(){
freopen("equation.in", "r", stdin);
freopen("equation.out", "w", stdout);
cin>>n>>m;
for (int i = 0; i <= n; ++i) {
scanf("%s", s);
int len = strlen(s);
int sign = 1;
for (int l = 0; l < len; ++l) {
if(s[l]=='-')
sign = -1;
else
for (int j = 0; j < 3; ++j)
a[i][j]=( a[i][j] * 10 + s[l]-'0' ) % prime[j];
}
if (sign == -1)
for (int j = 0; j < 3; ++j)
a[i][j] = prime[j] - a[i][j];
}
for (int j = 0; j < 3; ++j)
for(int i = 0; i < prime[j]; ++i)
f[i][j]=calc(i,j);
for (int i = 1; i <=m; ++i) {
bool flag = true;
for(int j = 0; j < 3; ++j)
if(f[i % prime[j]][j]) {
flag = false; break;
}
if(flag)
cnt[++cnt[0]] = i;
}
printf("%d\n", cnt[0]);
for (int i = 1; i <= cnt[0]; ++i)
printf("%d\n",cnt[i]);
return 0;
}