您的位置:首页 > 其它

usaco Chapter 1 Section 4

2012-05-23 17:33 274 查看
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] = {0, 1, 2, 3} ;
int b[8] = {0, 0, 0, 0, 1, 1, 1, 1} ;
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] = {0, 0, 0, 0, 0, 1, 2, 4, 5, 0, 1, 2, 3, 0,
0, 2, 3, 5, 6, 0, 1, 4, 7, 0, 0, 2, 4, 5,
6, 8, 3, 6, 9, 0, 0, 4, 5, 7, 8, 0, 7, 8,
9, 0, 0, 5, 6, 8, 9, 0} ;
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!=0) return 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, 0, sizeof(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] = {0, 0, 0, 0, 0, 1, 2, 4, 5, 0, 1, 2, 3, 0,
0, 2, 3, 5, 6, 0, 1, 4, 7, 0, 0, 2, 4, 5,
6, 8, 3, 6, 9, 0, 0, 4, 5, 7, 8, 0, 7, 8,
9, 0, 0, 5, 6, 8, 9, 0} ;
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!=0) return 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, 0, sizeof(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, 0, sizeof(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+1, 0, 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+1, 0, b, c+a) ;
}
int main(){
read ;
write ;
scanf("%d%d%d", &A, &B, &C) ;
memset(vis, 0, sizeof(vis)) ;
dfs(0, 0, 0, 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 ;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: