1. 程式人生 > >NOIP2014 提高組 day2

NOIP2014 提高組 day2

T1 無線網路發射器選址


一道很水的題,唯一需要注意的點就是判斷邊界,不然就會像我一樣只有10分

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long ll;
const int MAXN = 200;
ll d, n, k;
int max_x = -1, max_y = -1, min_x = 200, min_y = 200;
ll num[MAXN][MAXN];
ll ans_mea, ans_num;

ll cal(ll x, ll y)
{
	ll sum = 0;
	int lx = x-d, ly = y-d, rx = x+d, ry = y+d;
	if(lx<0) lx = 0;
	if(ly<0) ly = 0;
	if(rx>128) rx = 128;
	if(ry>128) ry = 128;	
	for(int i = lx; i <= rx; i++)
		for(int j = ly; j <= ry; j++)
			sum+=num[i][j];
	return sum;
}

int main()
{
//	freopen("wireless.in","r",stdin);
//	freopen("wireless.out","w",stdout);
	cin >> d >> n;
	int x, y;
	for(int i = 1; i <= n; i++)
	{
		cin >> x >> y >> k;
		num[x][y] = k;
		max_x = max(max_x, x);
		max_y = max(max_y, y);
		min_x = min(min_x, x);
		min_y = min(min_y, y);
	}
	for(int i = 0; i <= max_x; i++)
	{
		for(int j = 0; j <= max_y; j++)
		{
			ll tmp = cal(i, j);
			if(tmp==ans_num && tmp) ans_mea++;
			if(tmp > ans_num)
			{
				ans_num = tmp;
				ans_mea = 1;
			}
		}
	}
	printf("%lld %lld", ans_mea, ans_num);
	return 0;
}
/*
1
2
4 4 10
6 6 20
*/

T2 尋找道路


這道題可操作的一個小技巧就是建一個反圖,將不與終點直接或間接相連的點標記,剩下的部分還是比較簡單了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

const int MAXN = 5e5;
int n, m;
int head[MAXN], path[MAXN], ind[MAXN], vis[MAXN];
int sta, end, tot;
struct edge {
	int next, to;
}e[MAXN];
queue<int> q;

void add(int x, int y)
{
	e[++tot].next = head[x];
	head[x] = tot;
	e[tot].to = y;
}

void bfs(int x)
{
	vis[x] = 1;
	q.push(x);
	path[x] = 0;
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		for(int i = head[u]; i; i = e[i].next)
		{
			int v = e[i].to;
			if(!vis[v])
			{
				int v = e[i].to;
				path[v] = path[u] + 1;
				if(v == sta)
				{
					cout << path[v];
					exit(0);
				}
				vis[v] = 1;
				q.push(v);
			}
		}
	}
}

void judge(int x)
{
	for(int i = head[x]; i; i = e[i].next)
	{
		int v = e[i].to;
		vis[v] = 1;
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	int a, b;
	for(int i = 1; i <= m; i++)
	{
		scanf("%d%d", &a, &b);
		add(b, a);
		ind[a]++;
	}
	scanf("%d%d", &sta, &end);
	for(int i = 1; i <= n; i++)
	{
		if(!ind[i] && i!=end) judge(i);
	}
	bfs(end);
	printf("-1");
}

T3 解方程 

這道題的資料很大,但用純暴力也能拿30分,我們用在讀入的時候模大質數防止溢位,還有需要注意的一點就是為了防止被模數剛好是大質數的倍數,就多模了幾個

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long ll;
const ll INF = 999999999, MOD = 1000000007, MAXN = 1000100;
ll a[110], ans[MAXN];
ll n , m, cnt;

ll read()
{
    ll sum = 0,fg = 1;
    char c = getchar();
    while(c < '0' || c > '9')
	{
		if(c == '-') fg = -1;
		c = getchar();
	}
    while(c >='0' && c <='9')
    {
    	sum = sum*10 + c-'0';
		sum %= MOD;
		c = getchar();
	}
	return sum * fg;
}

ll f(ll h)
{
    ll sum = 0;
    for(ll i = n+1; i >= 1; i--)
	{
        sum = sum * h + a[i];
        sum = sum % MOD;
    }
    return sum;
}
int main()
{
    ll i,j;
    n = read(), m = read();
    for(ll i = 1; i <= n+1; i++)
        a[i] = read();
    for(ll i = 1; i <= m; i++)
        if(f(i) == 0)ans[++cnt] = i;
    printf("%lld\n",cnt);
    for(ll i = 1; i <= cnt; i++)printf("%lld\n", ans[i]);
    return 0;
}