P6550 [COCI2010-2011#2] LUNAPARK
题解
论证简单,构造逆天(好吧其实就是烦了点)。
每个格子是正整数,所以我们必然尝试多走格子。我们发现,只要 \(r,c\) 中有一个是奇数,我们就可以全部走到,构造很简单:我们找准奇数边,假设是 \(r\),蛇形地走,显然在奇数行我们会结束在末尾,在偶数行我们会结束在开头,所以是可行的。
if(r%2==1) {
for(int i=1;i<=r;i++) {
for(int j=1;j<c;j++)
if(i%2==1) putchar('R');
else putchar('L');
if(i!=r) putchar('D');
}
return 0;
}
if(c%2==1) {
for(int i=1;i<=c;i++) {
for(int j=1;j<r;j++)
if(i%2==1) putchar('D');
else putchar('U');
if(i!=c) putchar('R');
}
return 0;
}
我们现在只要考虑 \(r,c\) 均为偶数。
首先证明:此时不能走完。黑白染色易证(可以看其他题解)。
顺带的,我们可以证明:至少要抛弃一个白格才能走到终点(设起点是黑格)。
至于抛弃的白格有什么限制吗?答案是没有。
构造如下(以下建议画图理解):
我们每两行一考虑。
\(1\) 这两行没有出现要抛弃的点,且该点在这两行下面:按 \(RRR\cdots RDLLL\cdots LD\) 走。
\(2\) 这两行没有出现要抛弃的点,且该点在这两行上面:按 \(LLL\cdots LDRRR\cdots LR\) 走。
\(3\) 这两行出现了要抛弃的点:
再分类,我们每两列一考虑。
\((1)\) 这两列没有出现要抛弃的点,且该点在这两列右面:按 \(DRUR\) 走。
\((2)\) 这两行没有出现要抛弃的点,且该点在这两列左面:按 \(URDR\) 走。
\((3)\) 这两列出现了要抛弃的点:
分奇偶行考虑:
-
在奇数行:按 \(DRR\) 走。
-
在偶数行:按 \(RDR\) 走。
就构造完成了。
结束了吗?还有一个恶心的东西叫边界,一定不要走出去了!
完整代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd() {
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
int r,c,a[1005][1005];
int minn=LLONG_MAX,minx,miny;
signed main() {
cin>>r>>c;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
a[i][j]=rd();
if(r%2==1) {
for(int i=1;i<=r;i++) {
for(int j=1;j<c;j++)
if(i%2==1) putchar('R');
else putchar('L');
if(i!=r) putchar('D');
}
return 0;
}
if(c%2==1) {
for(int i=1;i<=c;i++) {
for(int j=1;j<r;j++)
if(i%2==1) putchar('D');
else putchar('U');
if(i!=c) putchar('R');
}
return 0;
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if((i+j)%2==1&&a[i][j]<minn)
minn=a[i][j],minx=i,miny=j;
for(int i=1;i<=r;i+=2) {
if(i+1<minx) {
for(int j=1;j<c;j++)
putchar('R');
putchar('D');
for(int j=1;j<c;j++)
putchar('L');
if(i+1!=r) putchar('D');
}
else if(i>minx) {
for(int j=1;j<c;j++)
putchar('L');
putchar('D');
for(int j=1;j<c;j++)
putchar('R');
if(i+1!=r) putchar('D');
}
else {
for(int j=1;j<=c;j+=2) {
if(j+1<miny) {
putchar('D');
putchar('R');
putchar('U');
if(j+1!=c) putchar('R');
}
else if(j>miny) {
putchar('U');
putchar('R');
putchar('D');
if(j+1!=c) putchar('R');
}
else {
if(minx%2==1) {
putchar('D');
putchar('R');
if(j+1!=c) putchar('R');
}
else {
putchar('R');
putchar('D');
if(j+1!=c) putchar('R');
}
}
}
if(i+1!=r) putchar('D');
}
}
return 0;
}
标签:两行,ch,putchar,int,题解,抛弃,P6550
From: https://www.cnblogs.com/operator-/p/17974766