usaco6.4.3 Wisconsin Squares

这是一篇关于农业编程挑战的文章,描述了如何帮助Farmer John将不同类型的奶牛群从一块田地转移到另一块田地,避免相同类型的牛群过于靠近。问题涉及到在一个4x4的网格上进行移动,确保每次移动后不会让同种类型的牛群相邻。题目要求首先移动D型牛群,并给出了一种解决方案和所有可能安排的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 原题

Wisconsin Squares

It's spring in Wisconsin and time to move the yearling calves to the yearling pasture and last year's yearlings to the greener pastures of the north 40.

Farmer John has five kinds of cows on his farm (abbreviations are shown in parentheses): Guernseys (A), Jerseys (B), Herefords (C), Black Angus (D), and Longhorns (E). These herds are arranged on the 16 acre pasture, one acre for each small herd, on a 4 x 4 grid (labeled with rows and columns) like this:

              1 2 3 4
             +-------
            1|A B A C
            2|D C D E
            3|B E B C
            4|C A D E

In the initial pasture layout, the herds total 3 A's, 3 B's, 4 C's, 3 D's, and 3 E's. This year's calves have one more D herd and one fewer C herd, for a total of 3 A's, 3 B's, 3 C's, 4 D's, and 3 E's.

FJ is extremely careful in his placement of herds onto his pasture grid. This is because when herds of the same types of cows are too close together, they misbehave: they gather near the fence and smoke cigarettes and drink milk. Herds are too close together when they are on the same square or in any of the eight adjacent squares.

Farmer John must move his old herd out of the field and his new herd into the field using his old brown Ford pickup truck, which holds one small herd at a time. He picks up a new herd, drives to a square in the yearling pasture, unloads the new herd, loads up the old herd, and drives the old herd to the north 40 where he unloads it. He repeats this operation 16 times and then drives to Zack's for low-fat yogurt treats and familiar wall decor.

Help Farmer John. He must choose just exactly the correct order to replace the herds so that he never puts a new herd in a square currently occupied by the same type of herd or adjacent to a square occupied by the same type of herd. Of course, once the old cows are gone and the new cows are in place, he must be careful in the future to separate herds based on the new arrangement.

Very important hint: Farmer John knows from past experience that he must move a herd of D cows first.

Find a way for Farmer John to move the yearlings to their new pasture. Print the 16 sequential herd-type/row/column movements that lead to a safe moving experience for the cows.

Calculate the total number of possible final arrangements for the 4x4 pasture and calculate the total number of ways those arrangements can be created.

PROGRAM NAME: wissqu

TIME LIMIT: 5 seconds

INPUT FORMAT

Four lines, each with four letters that denote herds.

SAMPLE INPUT (file wissqu.in)

ABAC
DCDE
BEBC
CADE

OUTPUT FORMAT

16 lines, each with a herd-type, row and column. If there are multiple solutions (and there are), you should output the solution for which the concatenated string ("D41C42A31 ... D34") of the answers is first in lexicographic order.

One more line with the total number of ways these arrangements can be created.

SAMPLE OUTPUT (file wissqu.out)

D 4 1
C 4 2
A 3 1
A 3 3
B 2 4
B 3 2
B 4 4
E 2 1
E 2 3
D 1 4
D 2 2
C 1 1
C 1 3
A 1 2
E 4 3
D 3 4
14925


二 分析

给定一张4*4的地图,地图上每一格只能是A-E的字母,初始数量分别为{3,3,4,3,3},要求每次修改一格,使得最终数量为{3,3,3,4,3},修改要求有两个:

1)第一次必须写入一个D;

2)每次在(i,j)写入字母c时,需保证(i,j)自身以及相邻的8格内都不含有c;

输出字典序的修改序列以及全部修改序列的数量。

挺无聊的一道搜索题,也不需要什么剪枝。只有一组测试样例。


三 代码

运行结果:

USER: Qi Shen [maxkibb3]
TASK: wissqu
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [1.708 secs, 4300 KB]

All tests OK.

Your program ('wissqu') produced all correct answers! This is yoursubmission #3 for this problem. Congratulations!


AC代码:

/*
ID:maxkibb3
LANG:C++
PROB:wissqu
*/

#include<iostream>
#include<fstream>
#include<vector>

using namespace std;

#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second

int dx[9][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {0, 0},
				{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};

ifstream fin("wissqu.in");
ofstream fout("wissqu.out");
string s[4];
bool vis[4][4];
int tot, num[5] = {3, 3, 3, 4, 3};
vector<pair<char, pii> > trace;

inline bool legal(int x, int y) {
	return (x >= 0 && x < 4 && y >= 0 && y < 4);
}

inline bool check(char c, int x, int y) {
	if(vis[x][y] || num[c - 'A'] == 0) {
		return false;
	}
	for(int i = 0; i < 9; i++) {
		int nx = x + dx[i][0], ny = y + dx[i][1];
		if(legal(nx, ny) && c == s[nx][ny]) {
			return false;
		}
	}
	return true;
}

void dfs(char c) {
    if(trace.size() == 16) {
        tot++;
        if(tot == 1) {
            for(int i = 0; i < 16; i++) {
                pair<char, pii> item = trace[i];
                fout << item.fi << " " << item.se.fi + 1 << " " << item.se.se + 1 << endl;
            }
        }
        return;
    }
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 4; j++) {
            if(check(c, i, j)) {
                char ori = s[i][j];
                s[i][j] = c;
                num[c - 'A']--;
                vis[i][j] = true;
                trace.pb(mp(c, mp(i, j)));
                for(int k = 0; k < 5; k++) {
                    if(num[k] > 0) {
                        dfs('A' + k);
                    }
                }
                if(trace.size() == 16) {
                    dfs('A');
                }
                trace.pop_back();
                vis[i][j] = false;
                num[c - 'A']++;
                s[i][j] = ori;
            }
        }
    }
}

int main() {
	for(int i = 0; i < 4; i++) {
		fin >> s[i];
	}
	dfs('D');
	fout << tot << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值