usaco Chapter 1 Section 4

1. 恶心的题..考虑了很久没好的想法,看了下报告,直接按图处理即可!搞毛啊,为什么能保证图示能包含所有情况??

枚举每个矩形位置和放置情况时用了next_permutation(),next_permutation()是生成下一字典序最小的排列,不包含当前排列,所以一般用do..while()语句。

code:

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<memory>
#include<algorithm>
#define read    freopen("packrec.in", "r", stdin)
#define write   freopen("packrec.out", "w", stdout)
#define rd      ifstream cout("packrec.out") ;
#define wt      ifstream cin("packrec.in") ;
using  namespace std ;
int data[ 5][ 2][ 2] ;
int a[ 4] = { 0123} ;
int b[ 8] = { 00001111} ;
int g, p, q, l, m, cnt ;
struct node{
     int w, h ;
}ans[ 1010] ;
int cmp( const  void *a,  const  void *b){
     return (*(node *)a).w < (*(node *)b).w ? - 1 :  1 ;
}
int max( int a,  int b){
     return a>b?a:b ;
}
void swap( int *a,  int *b){
    *a = *a + *b ;
    *b = *a - *b ;
    *a = *a - *b ;
}
void test( int w,  int h){
     if(w*h>m)    return ;
     if(w*h<m){
        m = w * h ;
        cnt =  0 ;
    }
     if(w>h) swap(&w, &h) ;
     for( int i= 0; i<cnt; i++)
         if(w==ans[i].w&&h==ans[i].h)  return ;
    ans[cnt].w = w ;
    ans[cnt++].h = h ;
}
void work(){
     int w, h, w1, w2, w3, w4, h1, h2, h3, h4 ;
     // printf("%d %d %d %d %d %d %d %d\n", a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3]) ;
    w1 = data[a[ 0]][b[ 0]][ 0], h1 = data[a[ 0]][b[ 0]][ 1] ;
    w2 = data[a[ 1]][b[ 1]][ 0], h2 = data[a[ 1]][b[ 1]][ 1] ;
    w3 = data[a[ 2]][b[ 2]][ 0], h3 = data[a[ 2]][b[ 2]][ 1] ;
    w4 = data[a[ 3]][b[ 3]][ 0], h4 = data[a[ 3]][b[ 3]][ 1] ;
    w = w1 + w2 + w3 + w4 ;
    h = max(max(max(h1, h2), h3), h4) ;
    test(w, h) ;
    w = max(w1+w2+w3, w4) ;
    h = max(max(h1, h2), h3) + h4 ;
    test(w, h) ;
    w = max(w1+w2, w3) + w4 ;
    h = max(max(h1, h2)+h3, h4) ;
    test(w, h) ;
    w = max(w1, w2) + w3 + w4 ;
    h = max(max(h1+h2, h3), h4) ;
    test(w, h) ;
    h = max(h1+h3, h2+h4) ;
     if(h3>=h2+h4)   w = max(w1, w3+max(w2, w4)) ;
     if(h4>=h1+h3)   w = max(w2, w4+max(w1, w3)) ;
    test(w, h) ;
     if(h3>h4&&h3<h2+h4) w = max(w1+w2, w3+max(w2, w4)) ;
     if(h3<h4&&h4<h1+h3) w = max(w1+w2, w4+max(w1, w3)) ;
     if(h3==h4)  w = max(w1+w2, w3+w4) ;
    test(w, h) ;
}
int main(){
    read ;
    write ;
     for( int i= 0; i< 4; i++){
        scanf( " %d%d ", &data[i][ 0][ 0], &data[i][ 0][ 1]) ;
        data[i][ 1][ 0] = data[i][ 0][ 1] ;
        data[i][ 1][ 1] = data[i][ 0][ 0] ;
    }
    cnt =  0 ;
    m =  40001 ;
     do
         do
            work() ;
         while(next_permutation(b, b+ 8)) ;
     while(next_permutation(a, a+ 4)) ;
    qsort(ans, cnt,  sizeof(ans[ 0]), cmp) ;
    printf( " %d\n ", m) ;
     for( int i= 0; i<cnt; i++)
        printf( " %d %d\n ", ans[i].w, ans[i].h) ;
     return  0 ;
}

 

 

 2. 枚举所有状态,4^9状态数可以过。可深搜可广搜,广搜时要用STL,STL中queue的pop()方法可以释放内存,用数组模拟的话会超内存。

code(dfs):

#include<cstdio>
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<memory>
#include<algorithm>
#define read    freopen("clocks.in", "r", stdin)
#define write   freopen("clocks.out", "w", stdout)
#define rd      ifstream cout("clocks.out") ;
#define wt      ifstream cin("clocks.in") ;
int data[ 11] ;
int tur[ 10][ 5] = { 00000124501230,
                   02356014700245,
                   68369004578078,
                   90056890} ;
int vis[ 11], f ;
void print(){
     int i, j ;
     for(i= 1; i< 10; i++)
         if(vis[i]){
            printf( " %d ", i) ;
            vis[i] -- ;
             break ;
        }
     for(i= 1; i< 10; i++)
         for(j= 0; j<vis[i]; j++)
            printf( "  %d ", i) ;
    printf( " \n ") ;
}
int check(){
     for( int i= 1; i<= 9; i++)
         if(data[i]% 12!= 0return  0 ;
     return  1 ;
}
void dfs( int id){
     if(f)    return ;
     if(id== 10){
         for( int i= 1; i< 10; i++)
             for( int j= 0; j<vis[i]; j++)
                 for( int k= 0; k< 5; k++)
                    data[tur[i][k]] +=  3 ;
         if(check()){
            f =  1 ;
            print() ;
        }
         for( int i= 1; i< 10; i++)
             for( int j= 0; j<vis[i]; j++)
                 for( int k= 0; k< 5; k++)
                    data[tur[i][k]] -=  3 ;
         return ;
    }
     for( int i= 0; i< 4; i++){
        vis[id] = i ;
        dfs(id+ 1) ;
    }
}
int main(){
    read ;
    write ;
     int i, j ;
    f =  0 ;
    memset(vis,  0sizeof(vis)) ;
     for(i= 1; i<= 9; i++)
        scanf( " %d ", &data[i]) ;
    dfs( 1) ;
     return  0 ;} 

 

 code(bfs):

#include<cstdio>
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<memory>
#include<queue>
#include<algorithm>
#define read    freopen("clocks.in", "r", stdin)
#define write   freopen("clocks.out", "w", stdout)
#define rd      ifstream cout("clocks.out") ;
#define wt      ifstream cin("clocks.in") ;
using  namespace std ;
int data[ 11] ;
int tur[ 10][ 5] = { 00000124501230,
                   02356014700245,
                   68369004578078,
                   90056890} ;
struct node{
     int id ;
     int d[ 11] ;
     int vis[ 11] ;
};
int check(node t){
     for( int i= 1; i<= 9; i++)
         if(t.d[i]% 12!= 0return  0 ;
     for( int i= 1; i< 10; i++)
         if(t.vis[i]){
            printf( " %d ", i) ;
            t.vis[i] -- ;
             break ;
        }
     for( int i= 1; i< 10; i++)
         for( int j= 0; j<t.vis[i]; j++)
            printf( "  %d ", i) ;
    printf( " \n ") ;
     return  1 ;
}
void bfs(){
     int i, j ;
    queue<node> q ;
    node te ;
     for(i= 1; i< 10; i++)
        te.d[i] = data[i] ;
    memset(te.vis,  0sizeof(te.vis)) ;
    te.id =  0 ;
    q.push(te) ;
     while(!q.empty()){
        node p = q.front() ;
        q.pop() ;
         if(check(p))  return ;
         for(i=p.id; i< 10; i++){
            node t = p ;
            t.vis[i] ++ ;
             if(t.vis[i]> 3)   continue ;
             for(j= 0; j< 5; j++)
                t.d[tur[i][j]] +=  3 ;
            t.id = i ;
            q.push(t) ;
        }
    }
}
int main(){
    read ;
    write ;
     int i, j ;
     for(i= 1; i<= 9; i++)
        scanf( " %d ", &data[i]) ;
    bfs() ;
     return  0 ;}

 

 3. 打好表直接模拟就行。

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<memory>
#include<algorithm>
#define read    freopen("ariprog.in", "r", stdin)
#define write   freopen("ariprog.out", "w", stdout)
#define rd      ifstream cout("clocks.out") ;
#define wt      ifstream cin("clocks.in") ;
int vis[ 500000], n, m ;
struct node{
     int a, b ;
}q[ 50001];
void init(){
    memset(vis,  0sizeof(vis)) ;
     for( int i= 0; i<=m; i++)
         for( int j= 0; j<=m; j++)
            vis[i*i+j*j] =  1 ;
}
int main(){
    read ;
    write ;
     int i, j, t= 0, count =  0  ;
    scanf( " %d%d ", &n, &m) ;
    init() ;
     for(i= 1; i<= 2*m*m/(n- 1); i++){
         for(j= 0; j+t*i<= 2*m*m; j++){
             if(!vis[j])  continue ;
            t =  1 ;
             while(vis[j+t*i]&&t<n)t ++ ;
             if(t>=n){
                q[count].a = j ;
                q[count++].b = i ;
                t -- ;
            }
        }
    }
     for(i= 0; i<count; i++)
        printf( " %d %d\n ", q[i].a, q[i].b) ;
     if(!count)  printf( " NONE\n ") ;
     return  0 ;
}

 

4. 原来做过一个倒水的题,跟这挺像。好难看的代码,咳...

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<memory>
#include<algorithm>
#define read    freopen("milk3.in", "r", stdin)
#define write   freopen("milk3.out", "w", stdout)
#define rd      ifstream cout("milk3.out") ;
#define wt      ifstream cin("milk3.in") ;
int A, B, C, cnt ;
int vis[ 21][ 21][ 21] ;
int ans[ 10001] ;
int cmp( const  void *a,  const  void *b){
     return *( int *)a < *( int *)b ? - 1: 1 ;
}
void dfs( int dep,  int a,  int b,  int c){
     if(a== 0)
        ans[cnt++] = c ;
     if(vis[a][b][c])     return ;
    vis[a][b][c] =  1 ;
     if(a+b+c!=C)     return ;
     if(c>=A-a) dfs(dep+ 1, A, b, c-(A-a)) ;
     else       dfs(dep+ 1, a+c, b,  0) ;
     if(b>=A-a) dfs(dep+ 1, A, b-(A-a), c) ;
     else       dfs(dep+ 1, a+b,  0, c) ;
     if(c>=B-b) dfs(dep+ 1, a, B, c-(B-b)) ;
     else       dfs(dep+ 1, a, b+c,  0) ;
     if(a>=B-b) dfs(dep+ 1, a-(B-b), B, c) ;
     else       dfs(dep+ 10, b+a, c) ;
     if(b>=C-c) dfs(dep+ 1, a, b-(C-c), C) ;
     else       dfs(dep+ 1, a,  0, c+b) ;
     if(a>=C-c) dfs(dep+ 1, a-(C-c), b, C) ;
     else       dfs(dep+ 10, b, c+a) ;
}
int main(){
    read ;
    write ;
    scanf( " %d%d%d ", &A, &B, &C) ;
    memset(vis,  0sizeof(vis)) ;
    dfs( 000, C) ;
    qsort(ans, cnt,  sizeof( int), cmp) ;
    printf( " %d ", ans[ 0]) ;
     for( int i= 1; i<cnt; i++)
         if(ans[i]!=ans[i- 1])
            printf( "  %d ", ans[i]) ;
    printf( " \n ") ;
     return  0 ;} 

 

你可能感兴趣的:(USACO)