IT民工
加油!

今天做的是吉林的省赛,我们队最后出了六题,其他队都是七题以上,感觉我坑了。

A:Welcome, 2008

这是一道签到题吧,陈兴看完就敲了,顺利一A。

我后面也写了一下:

#include <stdio.h>

int main()
{
    int n, h;
    while(scanf("%d", &n), n)
    {
        h = n << 1 | 1;
        for(int i = 1; i <= h; i ++)
        {
            if(i == 1 || i == n + 1 || i == (n << 1 | 1))
            {
                for(int j = 1; j <= n + 1; j ++)
                    printf("*");
                printf("\n");
            }
            else
            {
                printf("*");
                for(int j = 2; j <= n; j ++)
                    printf(" ");
                printf("*\n");
            }
        }
        printf("\n");
    }
    return 0;
}

B:StockWave

这应该是一道DP,求一个序列中上升下降上升下降这样波动的序列长度

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int MAXN = 1 << 10;
int f[2][MAXN];
double a[MAXN];
int n, ans;
void dp()
{
    ans = 0;
    f[0][0]=1;
    f[1][0]=0;
    for(int i = 1; i < n; i ++)
    {
        f[0][i] = 1;
        f[1][i] = 0;
        for(int j = 0; j <= i - 1; j ++)
        {
            if(a[j] > a[i])
            {
                f[0][i] = max(f[0][i], f[1][j] + 1);
            }
            if(a[j] < a[i])
            {
                f[1][i] = max(f[1][i], f[0][j] + 1);
            }
        }
        ans = max(ans, f[1][i]);
        ans = max(ans, f[0][i]);
    }
    if(ans < 3)
        ans = 0;
    printf("%d\n", ans);
}

int main()
{
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 0; i < n; i ++)
            scanf("%lf", &a[i]);
        dp();
    }
    return 0;
}

C:Central Avenue Road

枚举两棵树,并且判断他们连成的直线是否可以将所有的树尽量平均的分开,数目小于等于1就符合条件。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
const int MAXN = 105;
typedef long long LL;
const LL INF = 0x7FFFFFFFFFFFFFFFll;
LL x[MAXN], y[MAXN];
int lc, rc;
LL dis, ans;

int main()
{
    int n;
    while(scanf("%d", &n), n)
    {
        for(int i = 0; i < n; i ++)
        {
            scanf("%lld%lld", &x[i], &y[i]);
        }
        ans = INF;
        for(int i = 0; i < n - 1; i ++)
        {
            for(int j = i + 1; j < n; j ++)
            {
                lc = rc = 0;
                LL bx = x[j] - x[i];
                LL by = y[j] - y[i];
                for(int k = 0; k < n; k ++)
                {
                    if(k == i || k == j) continue;
                    LL cx = x[k] - x[i];
                    LL cy = y[k] - y[i];
                    LL temp = bx * cy - cx * by;
                    if(temp < 0)
                    {
                        rc ++;
                    }
                    else if(temp > 0) lc ++;

                }
                if(abs(lc - rc) > 1) continue;
                dis = bx * bx + by * by;
                if(ans > dis) ans = dis;
            }
        }
        double ret = sqrt(double(ans));
        printf("%.3f\n", ret);
    }
    return 0;
}

D:Function Value

A special function f is defined as follows:
f(n)=1 if n=1
f(n)=f(n-1) if n is prime integer.
f(n)=f(k)+1 if n is not prime, and k is the maximal factor of n.
Please calculate the function value for given integer n.

大叔秒掉了这道题:

#include<stdio.h>
#include <vector>
#include<string.h>
#include <math.h>

int ans[100000];
bool ishes[100000];
std::vector<int> pri;

void init()
{
    int i,j;
    for(i=2;i<100000;i++)
    {
        if(ishes[i])continue;
        for(j=i*2;j<100000;j+=i)
        {
            ishes[j]=true;
        }
    }
    for(i=2;i<100000;i++)
    {
        if(!ishes[i])pri.push_back(i);
    }
}

int cal(int n)
{
        if(n<100000)
        {
            if(ans[n]!=-1)return ans[n];
            if(!ishes[n])
            {
                int r=cal(n-1);
                ans[n]=r;
                return r;
            }
        }
        int i;
        int qr=sqrt((double)n);
        for(i=0;pri[i]<=qr;i++)
        {
            if(n%pri[i]==0)
            {
                int r=cal(n/pri[i])+1;
                if(n<100000)ans[n]=r;
                return r;
            }
        }
        return cal(n-1);
}

int main()
{
    memset(ans,-1,sizeof ans);
    ans[1]=1;
    init();
    int n;
    while(scanf("%d", &n) != EOF)
    {
        printf("%d\n",cal(n));
    }
    return 0;
}

E:Billboard

这道题也是大叔写的,可惜比赛的时候没过,之后改了一点就过了。妥妥的吉大模板,二分图最优匹配,KM算法。

#include<stdio.h>
#include <vector>
#include<string.h>
#include <math.h>
#include <algorithm>

#define MAXN 110
#define inf 1000000000
#define _clr(x) memset(x,-1,sizeof(int)*MAXN)

int kuhn_munkras(int m,int n,int mat[][MAXN],int * match1,int * match2)
{
    int s[MAXN],t[MAXN],l1[MAXN],l2[MAXN],p,q,ret=0,i,j,k;
    for(i=0;i<m;i++){
        for(l1[i]=-inf,j=0;j<n;j++)
            l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
        if(l1[i]==-inf)return -1;
    }
    for(i=0;i<n;l2[i++]=0);
    for(_clr(match1),_clr(match2),i=0;i<m;i++){
        for(_clr(t),s[p=q=0]=i;p<=q&&match1[i]<0;p++)
            for(k=s[p],j=0;j<n&&match1[i]<0;j++)
                if(l1[k]+l2[j]==mat[k][j]&&t[j]<0){
                    s[++q]=match2[j],t[j]=k;
                    if(s[q]<0)
                        for(p=j;p>=0;j=p)
                            match2[j]=k=t[j],p=match1[k],match1[k]=j;
                }
        if(match1[i]<0){
            for(i--,p=inf,k=0;k<=q;k++)
                for(j=0;j<n;j++)
                    if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
                        p=l1[s[k]]+l2[j]-mat[s[k]][j];
            for(j=0;j<n;l2[j]+=t[j]<0?0:p,j++);
            for(k=0;k<=q;l1[s[k++]]-=p);
        }
    }
    for(i=0;i<m;i++)
    {
        ret+=mat[i][match1[i]];
    }
    return ret;
}

char s1[110];
char s2[110];
char * p1,* p2;

int n,m;
int mat[110][110];
int match1[110],match2[110];

int main()
{
//freopen("c:\\e.in","r",stdin);
//freopen("c:\\m.txt","w",stdout);
    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        gets(s1);
        gets(s2);
        m=strlen(s1);
        n=strlen(s2);
        p1=s1;
        p2=s2;
        if(n<m)
        {
            std::swap(n,m);
            std::swap(p1,p2);
        }
        int i,j;
        for(i=0;i<m;i++)for(j=0;j<n;j++)
        {
            if(p1[i]==p2[j])
            {
                mat[i][j]=200-abs(i-j);
            }
            else
                mat[i][j]=0;
        }
        int r=kuhn_munkras(m,n,mat,match1,match2);
        int as=0;
        for(i=0;i<m;i++)if(mat[i][match1[i]]!=0)as++;
        printf("%d %d\n",as,as*200-r);
    }
    return 0;
}

F:CivilizationMap

这道题没看,据说很神。

G:What is your level?

这道题很遗憾,想多了,居然想到用线段树去做,突然发现写不了,比赛结束后问了苏犇,他一说我就只能呵呵了。

递推...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN = 200020;
const int MAXD = 405;
int p[MAXN][2], score[MAXD][MAXD], level[MAXD][MAXD];
int n;
void calc()
{
    level[401][400] = 0, level[400][401] = 0;

    for(int x = 400; x >= 0; x --)
    {
        for(int y = 400; y >= 0; y --)
        {
            if(score[x][y] > 0)
                level[x][y] = max(level[x + 1][y], level[x][y + 1]) + 1;
            else
                level[x][y] = max(level[x + 1][y], level[x][y + 1]);
        }
    }
}

void query()
{
    int id, q;
    scanf("%d", &q);
    while(q --)
    {
        scanf("%d", &id);
        printf("%d\n", level[p[id][0]][p[id][1]]);
    }
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d", &n);
        memset(score, 0, sizeof score);
        for(int i = 0; i < n; i ++)
        {
            scanf("%d%d", &p[i][0], &p[i][1]);
            score[p[i][0]][p[i][1]] ++;
        }
        calc();
        query();
    }
    return 0;
}

H:LampMatrix

这题是DFS,前面陈兴写了没过,大叔后面又写了一遍过了。

#include<stdio.h>
#include<string.h>

char mp[12][12];
unsigned ans[12][1<<20];
int msk;
int n,m;

void dfs(int i,int j,int s,int c,int fr)
{
    if(s==m)
    {
        ans[i][c]+=ans[i-1][j];
        ans[i][c]%=2008;
        return;
    }

    if(mp[i][s]=='.')
    {
        c|=j&(0x3<<2*s);
        dfs(i,j,s+1,c,fr);
    }
    else
    {
        int a=(j>>(2*s))&0x3;
        int d;
        for(d=1;d<=3;d++)
        {
            if(d==a||d==fr)continue;
            dfs(i,j,s+1,c|(d<<2*s),d);
        }
    }
}

int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        int i;
        bool hs=false;
        for(i=1;i<=n;i++)
        {
            scanf("%s",mp[i]);
            int j;
            for(j=0;j<m;j++)
            {
                if(mp[i][j]=='#')hs=true;
            }
        }
        if(!hs)
        {
            printf("0\n");
            continue;
        }
        memset(ans,0,sizeof ans);
        msk=1<<2*m;
        ans[0][0]=1;
        for(i=1;i<=n;i++)
        {
            int j;
            int pi=i-1;
            for(j=0;j<msk;j++)
            {
                if(ans[pi][j]==0)continue;
                dfs(i,j,0,0,0);
            }
        }
        unsigned r=0;
        for(i=0;i<msk;i++)
        {
            r+=ans[n][i];
            r%=2008;
        }
        printf("%u\n",r);
    }
    return 0;
}

I:Digit Game

这题是第二水的题,我敲的还复杂了...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

const int MAXN = 35;
char str1[MAXN], str2[MAXN], str3[MAXN];
int a[MAXN], b[MAXN];
void Minus(char *str1, char *str2, char *str3)
{
    int i, j, i1, i2, tmp, carry;
    int len1 = strlen(str1), len2 = strlen(str2);
    char ch;

    i1 = len1 - 1;
    i2 = len2 - 1;
    j = carry = 0;

    while(i2 >= 0)
    {
        tmp = str1[i1] - str2[i2] - carry;
        if(tmp < 0)
        {
            str3[j] = tmp + 10 + '0';
            carry = 1;
        }
        else
        {
            str3[j] = tmp + '0';
            carry = 0;
        }
        -- i1;
        -- i2;
        ++ j;
    }
    while(i1 >= 0)
    {
        tmp = str1[i1] - '0' - carry;
        if(tmp < 0)
        {
            str3[j] = tmp + 10 + '0';
            carry = 1;
        }
        else
        {
            str3[j] = tmp + '0';
            carry = 0;
        }
        -- i1;
        ++ j;
    }
    -- j;
    while(str3[j] == '0' && j > 0) -- j;
    str3[++ j] = '\0';
    for(i = 0, -- j; i < j; ++ i, -- j)
    {
        ch = str3[i];
        str3[i] = str3[j];
        str3[j] = ch;
    }
}

bool cmp(const int a, const int b)
{
    return a > b;
}

int main()
{
    while(scanf("%s", str1) != EOF)
    {
        memset(str2, 0, sizeof str2);
        memset(str3, 0, sizeof str3);
        int len = strlen(str1);
        for(int i = 0; i < len; i ++)
        {
            a[i] = b[i] = str1[i] - '0';
        }
        sort(a, a + len);
        sort(b, b + len, cmp);
        for(int i = 0; i < len; i ++)
            str1[i] = a[i] + '0';
        for(int i = 0; i < len; i ++)
            str2[i] = b[i] + '0';
        Minus(str2, str1, str3);
        int len3 = strlen(str3);
        for(int i = 0; i < len3; i ++)
            printf("%c", str3[i]);
        printf("\n");
    }
    return 0;
}

 

posted on 2012-10-04 23:53  找回失去的  阅读(201)  评论(0编辑  收藏  举报