Codeforces Round #142 (Div. 2)

  A.贪心,每次都选剩下的里面x最小的。

//Oct 1, 2012 7:42:03 PM 	bigoceanlhy 	230A - Dragons 	GNU C++ 	Accepted 	46 ms 	0 KB
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1000+5;
int N, s, x[MAXN], y[MAXN], r[MAXN];
bool cmp(const int a, const int b)
{
    return x[a] < x[b];
}
int main()
{
    scanf("%d%d", &s, &N);
    for (int i = 0; i < N; i++)
    {
        scanf("%d%d", &x[i], &y[i]);
        r[i] = i;
    }
    sort(r, r+N, cmp);
    bool flag = 1;
    for (int i = 0; i < N && flag; i++)
    {
        if (s > x[r[i]])
            s += y[r[i]];
        else
            flag = 0;
    }
    printf("%s\n", flag ? "YES" : "NO");
    return 0;
}


  B.满足条件的数是质数的平方。

//Oct 1, 2012 8:03:30 PM 	bigoceanlhy 	230B - T-primes 	GNU C++ 	Accepted 	296 ms 	1400 KB
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100000+5, MAXM = 1000000+5;
const double eps = 1e-8;
int N;
long long x;
bool is[MAXM]; int prm[MAXN];
int getprm(int n){
    int i, j, k = 0;
    int s, e = (int)(sqrt(0.0 + n) + 1);
    memset(is, 1, sizeof(is));
    prm[k++] = 2; is[0] = is[1] = 0;
    for (i = 4; i < n; i += 2) is[i] = 0;
    for (i = 3; i < e; i += 2) if (is[i]) {
        prm[k++] = i;
        for (s = i * 2, j = i * i; j < n; j += s)
            is[j] = 0;
    }
    for ( ; i < n; i += 2) if (is[i]) prm[k++] = i;
    return k;
}
int main()
{
    int c = getprm(1000003);
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        cin>>x;
        long long t = sqrt(x+0.0)+eps;
        if (t*t == x && is[(int)t])
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


  C.DP,d[i][j]表示前i层的第j列都为1的最小代价。

//Oct 1, 2012 10:49:36 PM 	bigoceanlhy 	229A - Shifts 	GNU C++ 	Accepted 	46 ms 	5100 KB
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 100+5, MAXM = 10000+5;
const int INF = 0x3f3f3f3f;
int N, M, d[MAXN][MAXM];
char mat[MAXN][MAXM];
int main()
{
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N; i++)
		scanf("%s", mat[i]+1);
	fill(d[0]+1, d[0]+1+M, 0);
	bool flag = 1;
	for (int i = 1; i <= N; i++)
	{
		flag = 0;
		for (int j = 1; j <= M; j++)
		{
			d[i][j] = INF;
			if (mat[i][j] == '1')
				flag = 1;
		}
		if (!flag)
			break;
		int nst;
		for (int j = 1; j <= M; j++)
			if (mat[i][j] == '1')
				nst = j;
		nst -= M;
		for (int j = 1; j <= M; j++)
		{
			if (mat[i][j] == '1')
				nst = j;
			d[i][j] = min(d[i][j], d[i-1][j]+j-nst);
		}
		for (int j = M; j >= 1; j--)
			if (mat[i][j] == '1')
				nst = j;
		nst += M;
		for (int j = M; j >= 1; j--)
		{
			if (mat[i][j] == '1')
				nst = j;
			d[i][j] = min(d[i][j], d[i-1][j]+nst-j);
		}
	}
	int ans = INF;
	for (int j = 1; j <= M; j++)
		ans = min(ans, d[N][j]);
	if (flag)
		printf("%d\n", ans);
	else
		printf("-1\n");
	return 0;
}


  D.大体思路就是直接最短路,松弛的时候加上等待的时间,要先把每个点有冲突的时刻的等待时间预处理出来。

//Oct 2, 2012 10:30:39 AM 	bigoceanlhy 	229B - Planets 	GNU C++ 	Accepted 	296 ms 	13000 KB
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int MAXN = 100000+5, MAXM = 200000+5;
const int INF = 0x3f3f3f3f;
int N, M, a, b, c, k, t[MAXN];
int e, head[MAXN], next[MAXM], v[MAXM];
int w[MAXM], d[MAXN];
bool inq[MAXN];
queue<int> Q;
map<int, int> wait[MAXN];
void addedge(int x, int y, int z)
{
	v[e] = y; w[e] = z;
	next[e] = head[x]; head[x] = e++;
}
void spfa(int s)
{
	for (int u = 1; u <= N; u++)
		d[u] = (u == s ? 0 : INF);
	Q.push(s);
	while (!Q.empty())
	{
		int u = Q.front(); Q.pop();
		inq[u] = 0;
		for (int i = head[u]; i != -1; i = next[i])
		{
			int x = d[u]+wait[u][d[u]]+w[i];
			if (x < d[v[i]])
			{
				d[v[i]] = x;
				if (!inq[v[i]])
				{
					Q.push(v[i]);
					inq[v[i]] = 1;
				}
			}
		}
	}
}
int main()
{
	memset(head, -1, sizeof(head));
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= M; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		addedge(a, b, c);
		addedge(b, a, c);
	}
	for (int i = 1; i <= N; i++)
	{
		scanf("%d", &k);
		for (int j = 1; j <= k; j++)
			scanf("%d", &t[j]);
		int last = 1;
		for (int j = k; j >= 1; j--)
		{
			if (j < k && t[j]+1 == t[j+1])
				wait[i][t[j]] = ++last;
			else
				wait[i][t[j]] = (last = 1);
		}
	}
	spfa(1);
	printf("%d\n", d[N] < INF ? d[N] : -1);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值