我刚刚参加了拉丁美洲总决赛的2009 ACM ICPC Programming Conest。这些问题适用于巴西,玻利维亚,智利等。
我的团队和我只能在十一个问题中完成两个问题(我认为第一次尝试不错)。
这是我们可以完成的。我很想看到代码的任何变化。完整的问题: ps:这些问题也可以在ICPC官方网站上找到。
在ACM的土地上统治着一位痴迷于秩序的虔诚的国王。王国有一个长方形,国王将领土划分为一个小矩形县的网格。在临死之前,国王将他们的县分配给他的儿子。
国王不知道他儿子之间的对抗:第一个继承人讨厌第二个而不是其他人,第二个人讨厌第三个而不是其他人,等等......最后,最后一个继承人讨厌第一个继承人,但不是其他继承人。 一旦国王去世,国王的儿子中的奇怪的竞争对手引发了王国的一场普遍的战争。攻击只发生在成对的相邻县之间(相邻的县是那些共享一个垂直或水平边界的县)。当X恨Y时,一个县X袭击了邻近的Y县。被攻击的郡总是被征服。所有同时进行的攻击和一系列同时攻击被称为战斗。经过一定数量的战斗后,幸存的儿子们休战,再也没有战斗过。例如,如果国王有三个儿子,名为 0,1和2 ,下图显示了在给定的初始土地分配的第一次战斗中会发生什么:
INPUT
输入包含几个测试用例。测试用例的第一行包含四个整数, N,R,C和K 。
继承人由从零开始的连续整数识别。接下来的R行中的每一行都包含由单个空格分隔的C个整数HeirIdentificationNumber(说明继承人拥有这片土地)。这是为了布置初始土地。
最后一个测试用例是由四个零分隔的行,用单个空格分隔。 (退出程序可以这么说)
输出
对于每个测试用例,你的程序必须打印R行,每行有C个整数,用与输入相同格式的单个空格分隔,表示所有战斗后的土地分布。
Sample Input: Sample Output:
3 4 4 3 2 2 2 0
0 1 2 0 2 1 0 1
1 0 2 0 2 2 2 0
0 1 2 0 0 2 0 0
0 1 2 2
另一个例子:
Sample Input: Sample Output:
4 2 3 4 1 0 3
1 0 3 2 1 2
2 1 2
答案 0 :(得分:5)
{$_=<>;($~,$R,$C,$K)=split;if($~){@A=map{$_=<>;split}1..$R;$x=0,
@A=map{$r=0;for$d(-$C,$C,1,-1){$r|=($y=$x+$d)>=0&$y<@A&1==($_-$A[$y])%$~
if($p=(1+$x)%$C)>1||1-$d-2*$p}$x++;($_-$r)%$~}@A
while$K--;print"@a\n"while@a=splice@A,0,$C;redo}}
地图保存在一维数组中。这不如二维解决方案优雅,但也更短。包含成语@A=map{...}@A
,其中所有的战斗都在大括号内进行。
答案 1 :(得分:2)
我有一段时间没玩过代码高尔夫拼图,所以我确定我错过了一些东西:
import sys
H,R,C,B=map(int,raw_input().split())
M=(1,0), (0,1),(-1, 0),(0,-1)
l=[map(int,r.split())for r in sys.stdin]
n=[r[:]for r in l[:]]
def D(r,c):
x=l[r][c]
a=[l[r+mr][c+mc]for mr,mc in M if 0<=r+mr<R and 0<=c+mc<C]
if x==0and H-1in a:n[r][c]=H-1
elif x-1in a:n[r][c]=x-1
else:n[r][c]=x
G=range
for i in G(B):
for r in G(R):
for c in G(C):D(r,c)
l=[r[:] for r in n[:]]
for r in l:print' '.join(map(str,r))
答案 2 :(得分:2)
g=loadstring("return io.read('*n')")repeat n=g()r=g()c=g()k=g()l={}c=c+1 for i=0,k do w={}for x=1,r*c do a=l[x]and(l[x]+n-1)%n w[x]=i==0 and x%c~=0 and g()or(l[x-1]==a or l[x+1]==a or l[x+c]==a or l[x-c]==a)and a or l[x]io.write(i~=k and""or x%c==0 and"\n"or w[x].." ")end l=w end until n==0
答案 3 :(得分:1)
let R()=System.Console.ReadLine().Split([|' '|])|>Array.map int
let B(a:int[][]) r c g=
let n=Array.init r (fun i->Array.copy a.[i])
for i in 1..r-2 do for j in 1..c-2 do
let e=a.[i].[j]-1
let e=if -1=e then g else e
if a.[i-1].[j]=e||a.[i+1].[j]=e||a.[i].[j-1]=e||a.[i].[j+1]=e then
n.[i].[j]<-e
n
let mutable n,r,c,k=0,0,0,0
while(n,r,c,k)<>(0,2,2,0)do
let i=R()
n<-i.[0]
r<-i.[1]+2
c<-i.[2]+2
k<-i.[3]
let mutable a=Array.init r (fun i->
if i=0||i=r-1 then Array.create c -2 else[|yield -2;yield!R();yield -2|])
for j in 1..k do a<-B a r c (n-1)
for i in 1..r-2 do
for j in 1..c-2 do
printf "%d" a.[i].[j]
printfn ""
使阵列大到足以在外面放置一个额外的“-2”边框 - 这种方式可以向左/向上/向右/向下看而不用担心越界异常。
B()是战斗功能;它克隆数组数组并计算下一个布局。对于每个方格,看看上/下/左/右是否是讨厌你的人(敌人'e'),如果是,他会把你带走。
主while循环只读取输入,运行k次迭代的战斗,并按照规范打印输出。
输入:
3 4 4 3
0 1 2 0
1 0 2 0
0 1 2 0
0 1 2 2
4 2 3 4
1 0 3
2 1 2
0 0 0 0
输出:
2220
2101
2220
0200
103
212
答案 4 :(得分:1)
此代码的灵感来自Steve Losh' answer:
import sys
A=range
l=lambda:map(int,raw_input().split())
def x(N,R,C,K):
if not N:return
m=[l()for _ in A(R)];n=[r[:]for r in m]
def u(r,c):z=m[r][c];n[r][c]=(z-((z-1)%N in[m[r+s][c+d]for s,d in(-1,0),(1,0),(0,-1),(0,1)if 0<=r+s<R and 0<=c+d<C]))%N
for i in A(K):[u(r,c)for r in A(R)for c in A(C)];m=[r[:]for r in n]
for r in m:print' '.join(map(str,r))
x(*l())
x(*l())
最小化:
import Monad
import Array
import List
f=map
d=getLine>>=return.f read.words
h m k=k//(f(\(a@(i,j),e)->(a,maybe e id(find(==mod(e-1)m)$f(k!)$filter(inRange$bounds k)[(i-1,j),(i+1,j),(i,j-1),(i,j+1)])))$assocs k)
main=do[n,r,c,k]<-d;when(n>0)$do g<-mapM(const d)[1..r];mapM_(\i->putStrLn$unwords$take c$drop(i*c)$f show$elems$(iterate(h n)$listArray((1,1),(r,c))$concat g)!!k)[0..r-1];main
上面的代码基于下面的(希望可读的)版本。与sth's answer最显着的区别可能是此代码使用Data.Array.IArray
而不是嵌套列表。
import Control.Monad
import Data.Array.IArray
import Data.List
type Index = (Int, Int)
type Heir = Int
type Kingdom = Array Index Heir
-- Given the dimensions of a kingdom and a county, return its neighbors.
neighbors :: (Index, Index) -> Index -> [Index]
neighbors dim (i, j) =
filter (inRange dim) [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]
-- Given the first non-Heir and a Kingdom, calculate the next iteration.
iter :: Heir -> Kingdom -> Kingdom
iter m k = k // (
map (\(i, e) -> (i, maybe e id (find (== mod (e - 1) m) $
map (k !) $ neighbors (bounds k) i))) $
assocs k)
-- Read a line integers from stdin.
readLine :: IO [Int]
readLine = getLine >>= return . map read . words
-- Print the given kingdom, assuming the specified number of rows and columns.
printKingdom :: Int -> Int -> Kingdom -> IO ()
printKingdom r c k =
mapM_ (\i -> putStrLn $ unwords $ take c $ drop (i * c) $ map show $ elems k)
[0..r-1]
main :: IO ()
main = do
[n, r, c, k] <- readLine -- read number of heirs, rows, columns and iters
when (n > 0) $ do -- observe that 0 heirs implies [0, 0, 0, 0]
g <- sequence $ replicate r readLine -- read initial state of the kingdom
printKingdom r c $ -- print kingdom after k iterations
(iterate (iter n) $ listArray ((1, 1), (r, c)) $ concat g) !! k
main -- handle next test case
答案 5 :(得分:1)
有点晚了,但是......一维数组中的数据。使用2-D阵列,解决方案的时间长约30个字符。
NR<2{N=$1;R=$2;C=$3;K=$4;M=0}NR>1{for(i=0;i++<NF;)X[M++]=$i}END{for(k=0;k++<K;){
for(i=0;i<M;){Y[i++]=X[i-(i%C>0)]-(b=(N-1+X[i])%N)&&X[i+((i+1)%C>0)]-b&&X[i-C]-b
&&[i+C]-b?X[i]:b}for(i in Y)X[i]=Y[i]}for(i=0;i<M;)printf"%s%d",i%C?" ":"\n",
X[i++]}