Codeforces Round #142 (Div. 2) 解题报告

230A  A. Dragons

贪心水题

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int x, y;
}p[1003];
bool cmp(node a, node b)
{
    return a.x < b.x || a.x == b.x && a.y > b.y;
}
int main()
{
    int i, j;
    int n, s;
    while( ~scanf("%d%d", &s, &n))
    {
        for(i = 0; i < n; i++)
            scanf("%d%d", &p[i].x, &p[i].y);
        sort(p, p + n, cmp);
        for(i = 0; i < n; i++)
        {
            if(s > p[i].x) s += p[i].y;
            else break;
        }
        if(i == n) puts("YES");
        else puts("NO");
    }
    return 0;
}

230B B. T-primes

题目要求的数为某个素数的平方数,  打个1000000内的素数表, 水题。

View Code
#include<stdio.h>
#include<string.h>
#include<math.h>
#define lld __int64
int vis[1000003];
int n;
lld m;
int main()
{
    int i, j;
    for(i = 2; i <= 1000; i++)
    {
        if(!vis[i])
        {
            for(j = i * i; j <= 1000000; j += i)
                vis[j] = 1;
        }
    }
    while( ~scanf("%d", &n))
    {
        while(n--)
        {
            scanf("%I64d", &m);
            if(m <= 3) { puts("NO"); continue; }
            lld tmp = (lld) sqrt(m * 1.0 + 0.5);
            if(tmp * tmp == m && !vis[tmp]) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}

229A  A. Shifts

用数组保存移动到所有行所需要的步数,暴力求最小值。

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n, m;
int l[103][10003]; //保存左边移动过来的值
int r[103][10003]; //保存右边移动过来的值
char a[103][10003];
int minz(int a, int b)
{
    return a < b ? a : b;
}
int main()
{
    int i, j, k, tot;
    bool flag, ok;
    scanf("%d%d", &n, &m);
    ok = 0;
    for(i = 0; i < n; i++)
    {
            scanf("%s", a[i]);
            flag = 1;
            for(j = 0; j < m; j++)
                if(a[i][j] == '1')
                {
                    flag = 0;
                    tot = 1;
                    for( k = (j + 1) % m; a[i][k] != '1'; k = (k + 1) % m)
                        l[i][k] = tot++;
                    tot = 1;
                    for( k = (j + m - 1) % m; a[i][k] != '1'; k = (k + m - 1) % m)
                        r[i][k] = tot++;
                }
            if(flag) ok = 1;
    }   
        if(ok) { puts("-1"); return 0; }
        int ans = n * m, tmp;
        for(j = 0; j < m; j++)
        {
            tmp = 0;
            for(i = 0; i < n; i++)
                tmp += minz(l[i][j], r[i][j]);
            ans = minz(ans, tmp);
        }
        printf("%d\n", ans);
    return 0;
}

用强大的vector

View Code
#include<stdio.h>
#include<string.h>
#include<vector>  
using namespace std;
int sum[100004];
char map[100004];
vector<int> v;
int minz(int a, int b)
{
    return a < b ? a : b;
}
int main()
{
    int i, j;
    int n, m;
    bool flag;
    while( ~scanf("%d%d", &n, &m))
    { 
        flag = 1;
        memset(sum, 0, sizeof(sum));
        for(i = 0; i < n; i++)
        {
            scanf("%s", map);            
            if(!flag) continue; 
            v.clear();
            v.resize(1);
            for(j = 0; j < m; j++)
                if(map[j] == '1') v.push_back(j);
            if(v.size() == 1)
            { flag = 0; continue; }
            v[0] = v.back() - m;
            v.push_back(v[1] + m);
            int k = 0; // pay attention the pos of "k", outside the circulation j;
            for(j = 0; j < m; j++)
            {
                while(v[k+1] <= j) k++;
                sum[j] += minz(j - v[k], v[k+1] - j);
            }
        }
        if(!flag) puts("-1");
        else
        {
            int k = 0;
            for(i = 1; i < m; i++)
                if(sum[k] > sum[i]) k = i;
            printf("%d\n", sum[k]);
        }
    }
    return 0;
}

229B B. Planets

最短路模板修改题, 可以用dijkstra + heap   or   SPFA  

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 100004
struct edge
{
    int v, next, w;
}list[maxn<<1];

int tot, head[maxn];
int n, m;

void init()
{
    tot = 0;
    memset(head, -1, sizeof(int)*(n+1));
}

void add(int s, int t, int w)
{
    list[tot].v = t;
    list[tot].w = w;
    list[tot].next = head[s];
    head[s] = tot++;
}

int vis[maxn];
vector<int> v[maxn];

struct node
{
    int x, c;
    node(){};
    node(int xx, int cc) : x(xx), c(cc){}
    friend bool operator<(node a, node b) 
    {
        return a.c > b.c;
    }
}s, p;
int bfs()
{
    priority_queue<node> q;
    int i;
    memset(vis, 0, sizeof(int)*(n+1));
    q.push(node(0, 0));
    while(!q.empty())
    {
        s = q.top();
        q.pop();
        //printf("x = %d c = %d\n", s.x, s.c);
        if(vis[s.x]) continue;
        vis[s.x] = 1;
        if(s.x == n - 1) return s.c;
        vector<int>:: iterator it;
        it = lower_bound(v[s.x].begin(), v[s.x].end(), s.c);
        while(it != v[s.x].end())
        {
            if(*it != s.c) break;
            it++;
            s.c++;
        }
        for(i = head[s.x]; i != -1; i = list[i].next)
        {
            int v = list[i].v;
            int w = list[i].w;
            if(!vis[v])
            {
                p = s;
                p.x = v;
                p.c += w;
                q.push(p);
            }
        }
    }
    return -1;
}
int main()
{
    int i, j, k;
    int x, y, z;
    while( ~scanf("%d%d", &n, &m))
    {
        init();
        while(m--)
        {
            scanf("%d%d%d", &x, &y, &z);
            x--; y--;
            add(x, y, z);
            add(y, x, z);
        }
        for(i = 0; i < n; i++)
        {
            v[i].clear();
            scanf("%d", &m);
            while(m--)
            {
                scanf("%d", &k);
                v[i].push_back(k);
            }
        }
        printf("%d\n", bfs());
    }
    return 0;
}

229C C. Triangles

数学题,找规律。ans = 总三角形数C(3,n) - 被破坏的三角形数

如果一个三角形被破坏了,那么一定有其中一条边在一个图另两条边在另外的图中,统计每个点在m条边组成的图中的度数,这样可以算出以当前点为三角形中的一个点时被破坏的三角形的个数,加起来之后除以2(因为一个被破坏的三角形被计算了两次)得到被破坏的个数。

 

View Code
#include<stdio.h>
#include<string.h>
__int64 d[1000003], n;
int main()
{
    int i, j, m, x;
    __int64 ans;
    while( ~scanf("%I64d%d", &n, &m))
    {
        memset(d, 0, sizeof(d));
        ans = (n - 2) * (n - 1) * n / 3;
        for(i = 1; i <= 2 * m; i++)
            scanf("%d", &x), d[x]++;
        for(i = 1; i <= n; i++)
            ans -= d[i] * (n - 1 - d[i]);
        printf("%I64d\n", ans/2);
    }
    return 0;
}

 

 

 

posted @ 2012-10-05 21:56  To be an ACMan  Views(371)  Comments(0)    收藏  举报