这个专题充分暴露了不认真思考的缺点,总是感觉差不多就下手。
对于A题目,以为是强连通分量缩点。但实际上是求桥。
并考虑:1.重边 2.权重为0则初始值不能赋值为0,当选取权重为0的边答案为1 3.没有答案。
对于B题目,起初想得很复杂,以为是动态规划,一直在思考转移方程。但其实DFS就可以,但漏掉了形成正方形的另一个条件,底边平行。
对于C题目,这里又出现了漏洞(直接DFS不用考虑这些)就是停止的情况用循环写要格外考虑。可我却模拟做,用循环来写。
这里还自己编了点数据。
/*
4
0 3 1
0 0 3
4
0 2 1
0 3 0
4
0 3 3
0 0 3
4
0 3 3
0 0 0
4
0 3 3
1 3 1
4
0 0 0
0 3 1
*/#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#define maxn 1005
using namespace std;
int N,M;
int lr,lc,ld,tr,tc,td;
int direct[4][2]={0,1, 1,0, 0,-1, -1,0};
struct point
{
int lt,tt;
}P[maxn][maxn];
int main()
{
int i,j,k;
int flag;
while(scanf("%d",&N))
{
if(N==0)
break;
scanf("%d%d%d%d%d%d",&lr,&lc,&ld,&tr,&tc,&td);
if(lr==tr&&lc==tc)
{
printf("%d %d\n",lr,lc);
continue;
}
memset(P,-1,sizeof(P));
k=1; P[lr][lc].lt=k++;
while(1)
{
while(1)
{
if(lr+direct[ld][0]<0 || lr+direct[ld][0]>=N || lc+direct[ld][1]<0 || lc+direct[ld][1]>=N || P[ lr+direct[ld][0] ][ lc+direct[ld][1] ].lt!=-1)
break;
lr+=direct[ld][0];lc+=direct[ld][1];
P[lr][lc].lt=k++;
}
ld++;
ld%=4;
if(lr+direct[ld][0]<0 || lr+direct[ld][0]>=N || lc+direct[ld][1]<0 || lc+direct[ld][1]>=N || P[ lr+direct[ld][0] ][ lc+direct[ld][1] ].lt!=-1)
break;
}
/*for(i=0;i<N;i++)
{for(j=0;j<N;j++)
printf("%2d ",P[i][j].lt);
printf("\n");}*/
j=1;P[tr][tc].tt=j++;
flag=0;
while(1)
{
while(1)
{
if(tr+direct[td][0]<0 || tr+direct[td][0]>=N || tc+direct[td][1]<0 || tc+direct[td][1]>=N || P[ tr+direct[td][0] ][ tc+direct[td][1] ].tt!=-1)
break;
tr+=direct[td][0];tc+=direct[td][1];
P[tr][tc].tt=j++;
if(P[tr][tc].lt==P[tr][tc].tt || (P[lr][lc].lt<P[lr][lc].tt))
{
flag=1;break;
}
//if(j>=k)break;
}
//if(j>=k)break;
if(flag==1) break;
td+=3;
td%=4;
if(tr+direct[td][0]<0 || tr+direct[td][0]>=N || tc+direct[td][1]<0 || tc+direct[td][1]>=N || P[ tr+direct[td][0] ][ tc+direct[td][1] ].tt!=-1)
break;
}
if(P[tr][tc].lt>=P[tr][tc].tt)
printf("%d %d\n",tr,tc);
else if(flag==0)
printf("-1\n");
else
printf("%d %d\n",tr,tc);
}
return 0;
}
ALL in all,下次写题目先把情况考虑周全。问题建模正确再开始。特殊数据自己要先构建出来。
尤其是为0,重点,等