USACO Section 4.3 题解

Buy Lower, Buy Lower (buylow)

最长下降子序列,在计算方案数的时候用到大整数加法。

/*
ID:###
PROG:buylow
LANG:C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
int a[5011],f[5011];
typedef int arr[500];
arr num[5010];
int b[5011];
bool u[5011];
int n;

void init()
{
    int i,j,k;
    freopen("buylow.in","r",stdin);
    freopen("buylow.out","w",stdout);
    n = 0; i = -1;
    scanf("%d",&k);
    while (k --)
    {
        scanf("%d",&j);
        if ( j != i) 
        {
            a[++n] = j;
        }
        i = j;
    }
    a[++n] = -1;
}

void add(arr a,arr b)
{
    int i,j,k;
    k = a[0];
    if ( k < b[0] ) k = b[0];
    for ( i = 1; i <= k; i++) a[i] +=b[i];
    for ( i = 1; i <= k; i++) {a[i+1]+=a[i]/10;a[i] = a[i] % 10;}
    if (a[k+1] !=0) a[0] = k+1;else a[0] = k; 
}
void solve()
{
    int i,j,k,m;
    for ( i = 1; i <= n; i++)
    {
        memset(u,0,sizeof(u));
        num[i][0] = 1;
        k = i; m = 0;
        for (j = i - 1; j; j--)
        {
            if (a[j] > a[i] )
            if(    f[j] > f[k] )
            {
                k = j;
                b[m = 1] = j;    
            }else 
                if (f[j] == f[k]) 
                    b[++m] = j;
        }
        f[i] = f[k] + 1;
        if (f[i] == 1) num[i][0] = num[i][1] = 1;
        for ( j = 1; j <= m; j++)
        {    
            for ( k = 1; k < j; k++)
                if (a[b[k]] == a[b[j]]) break; 
            if ( k == j ) add(num[i],num[b[j]]);
        }
    }

    printf("%d ",f[n]-1);
    for ( i = num[n][0]; i ;i--) 
        printf("%d",num[n][i]);
    printf("\n");

}
int main()
{
    init();
    solve();
    return 0;
}
View Code

The Primes (prime3)

搜索题,卡了我好久。

这道题先筛选出符合条件的质数,然后按照一定顺序进行搜索。我先搜索第一行,第一列,两个对角线,第五行,然后计算第三行2,4个数,第五列,然后计算剩余的数,并检验是否符合条件。最后排序输出。

/*
ID:###
LANG:C++
PROG:prime3
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <memory.h>
using namespace std;
bool b[100001]={};
int n,m;
int w[5][5];
int ord[11]={};
int ord2[11]={};
int a[10000][5];
int sum = 0;
int a2[10000][5];
int t;
int tot = 0;
int c[1000][5][5];
int d[1000];
void print2()
{
    int i; int  j  =0;
    for ( i = 0; i < 5; i++)
    {
        j = j*10 +w[i][i];
    }
}
bool cmp(int p,int q)
{
    int i,j;
    for ( i = 0; i <5;i++)
        for ( j = 0; j < 5; j++)
        {
            if (c[p][i][j]<c[q][i][j] ) return 1;else 
                if (c[p][i][j] >c[q][i][j]) return 0;
        }
    return 1;
}
void init()
{
    freopen("prime3.in","r",stdin);
    freopen("prime3.out","w",stdout);
    int i,j,k;
    i = 2;
    for ( i = 0; i < 1000; i ++) d[i] = i;
    i = 2;
    while ( i < 100000 )
    {
        if ( !b[i] ) 
        {
        j = 2*i;
        while ( j < 100000)
        {
            b[j] = 1;
            j += i;
        }
        }
        i ++;
    }
    cin >> m >>n;
    for ( i = 10000; i < 100000; i++)
    {
        if (!b[i])
        {
            j = i; k = 0;
            while ( j) {k += j % 10; j = j /10;}
            if ( k == m )
            {
                sum ++; j = i;
                for ( k = 4; k >=0; k--)
                {
                    a[sum][k] = j %10;
                    j = j /10;
                }    
                j = a[sum][0];
                if ( ord[j] == 0 ) 
                {
                    ord[j] = sum;
                }    
            }
        }
    }
    ord[10] = sum + 1;
    for ( i = 9; i; i--) 
        if( ord[i] == 0 ) ord[i] = ord[i + 1];
    k = 0;
     for ( i = 1; i <= sum; i++)
     {
         int flag = 0;
         for( j = 0;j < 5; j++) 
         {
             int p = a[i][j];
             if (p != 1&&p!=3&&p!=7&&p!=9) {flag = 1;break;}
         }
         if ( flag ) continue;
         k++;
         for ( j = 0; j < 5; j++) a2[k][j] = a[i][j];
         if (ord2[a[i][0]] == 0) ord2[a[i][0]] = k;
     }
     ord2[10] = k + 1;
     for( i = 9; i ;i --)
         if( ord2[i] == 0) ord2[i] = ord2[i+1];
}
void sa()
{
    tot ++;
    for ( int i = 0; i < 5; i++)
    {
        for ( int j = 0; j < 5; j++)
        {
            c[tot][i][j] = w[i][j];
        }
    }
}
void dfs (int vt)
{
    int i,j,p,q,k,temp;
    if ( vt == 1)
    {
        for ( i = ord2[w[4][0]]; i < ord2[w[4][0] + 1]; i ++)
        {
            if ( w[4][4] == a2[i][4]) 
            {
                w[4][1] = a2[i][1];w[4][2] = a2[i][2]; w[4][3] = a2[i][3];
                w[2][1] = m - w[0][1] -w[1][1] -w[3][1]-w[4][1]; if (w[2][1] < 0||w[2][1] >9) continue;
                temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][1]; if (b[temp]) continue;
                w[2][3] = m - w[0][3] - w[1][3] - w[3][3] - w[4][3]; if( w[2][3] < 0||w[2][3] >9) continue;
                temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][3]; if (b[temp]) continue;
                w[2][4] = m - w[2][0] - w[2][1] - w[2][2] - w[2][3]; if (w[2][4] <0||w[2][4] > 9) continue;
                temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[2][k]; if (b[temp]) continue;
                for ( j = ord2[w[0][4]]; j < ord2[w[0][4]+1]; j++)
                {
                    if (w[2][4] == a2[j][2] && w[4][4] == a2[j][4])
                    {
                        w[1][4] = a2[j][1];w[3][4] = a2[j][3];
                        w[1][2] = m - w[1][0]- w[1][1] - w[1][3] - w[1][4]; if ( w[1][2] < 0 ||w[1][2] >9) continue;
                        temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[1][k]; if (b[temp]) continue;
                        w[3][2] = m -w[3][0] - w[3][1] - w[3][3] - w[3][4];
                        if( w[3][2] <0||w[3][2]>9) continue;
                        temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[3][k]; if (b[temp]) continue;

                        temp = 0;for ( k = 0; k < 5; k++) temp = temp*10+w[k][2]; if (b[temp]) continue;
                        if ( m == w[0][2] + w[1][2] + w[2][2] + w[3][2] + w[4][2]) 
                            sa();
                    }
                }
            }
        }
    }else
    {}
}
void solve()
{
    int i,j,k,p,q; 
    int flag = 0;
    for ( i = ord[n]; i < ord[n+1]; i++)
    {

        for ( k = 0; k < 5; k++){ w[0][k] = a[i][k]; if ( a[i][k] == 0) flag = 1;}
            if ( flag ) {flag = 0;continue;}
        for ( j = ord[n]; j < ord[n+1]; j++)
        {
            for ( k = 1; k < 5; k++){ w[k][0] = a[j][k]; if ( a[j][k] ==0) flag = 1;}
            if( flag ) {flag = 0;continue;}
            for ( p = ord[n] ; p < ord[n +1];p++)
            {
                for ( k = 1; k < 5; k++) w[k][k] = a[p][k];
    
                for ( q = ord[w[4][0]]; q< ord[w[4][0] + 1]; q++)
                {
                    if (a[q][2] == w[2][2] && a[q][4] == w[0][4])
                    {
                        w[3][1] = a[q][1]; w[1][3] = a[q][3];
                        dfs (1);
                    }
                }
            }
        }    
    }

}

void print()
{
    int i,j,k;
    sort(d+1,d+tot+1,cmp);
    for ( i = 1; i <= tot; i++)
    {
        for ( j = 0; j < 5; j++)
        {
            for( k = 0; k < 5; k ++)
                cout <<c[d[i]][j][k];
            cout <<endl;
        }
        if ( i != tot) cout<<endl;
    }
    if ( tot == 0) cout <<"NONE"<<endl;
}

int main()
{
    init();
    solve();
    print();
    return 0;
}
View Code

Street Race (race3)


先做一遍floyed,然后枚举每个点,删除它并从起点深搜,判断是否为unavoidable,如果从起点可以到达i并且从这个点也能到达i,则不满足第二问条件。

Letter Game (lgame)

最多只有两个单词进行组合。枚举就可以通过。

/*
ID:###
LANG:C++
PROG:lgame
*/
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <string>
using namespace std;
int m,n;
int maxvalue = 0;
int b[26]={};
int cost[]={2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7};
string s;
string r[40000];
string rr[40000];
int fit(string w)
{
    int c[26];
    int i,j,k;  k = 0;
    for ( i = 0; i < 26; i ++) c[i] = b[i];
    for ( j = 0; j < w.length(); j++)
    {
        if ((--c[w[j]-97]) < 0) return 0;
        k += cost[w[j] - 97];
    }
    return k;
}
void init()
{
    n = m = 0;
    freopen("lgame.in","r",stdin);
    freopen("lgame.out","w",stdout);
    ifstream fd("lgame.dict");
    cin>>s;
    int i,j,k;
    for ( i = 0; i < s.length(); i++)
        b[s[i]-97] ++;
    string s1="";
    fd>>s1;
    while( s1 != ".")
    {
        if (fit(s1))
        {
            rr[++n] = s1;
        }    
        fd>>s1;
    }
}
void solve()
{
    int i,j,k;
    for ( i = 1; i <= n; i++)
    {    
        k = fit(rr[i]);
        if ( k >= maxvalue) 
        {
            if ( k > maxvalue) {m = 0; maxvalue = k;}
            r[++m] = rr[i];
        }
    

        for(  j = i + 1; j <=n; j++)
        {        
    
            k = fit(rr[i]+rr[j]);
            if ( k >= maxvalue) 
            {
                if ( k > maxvalue) {m = 0; maxvalue = k;}
                r[++m] = rr[i]+" "+rr[j];
            }
        
        }
    }
    cout << maxvalue <<endl;
    for ( i = 1; i <= m ;i++)
        cout<<r[i]<<endl;
}
int main()
{
    init();
    solve();
    return 0;
}
View Code

 

 

转载于:https://www.cnblogs.com/caxis/p/3215367.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值