总体分析:
第一道题:一个字!水!!,只不过看数据的话那个第五个测评点会非常大,需要一个并查集剪枝维护才能A,但是考试的时候过了样例,就没考虑那么多,一共6个点,5个点开考20分钟秒过……
第二道题:四个字!半水不水!!,做题时发现呵呵呵呵……(苦笑)把DFS全写完,样例过了,但是乍得一看数据范围,一下子就懵了。最后没有改用BFS,A过3个点,另外两个点栈溢出,开考50分钟后写完。
第三道题:如果你知道样例,基本上可以放弃了。可惜我用30分钟写了一个FLOYD无敌大暴力,五层循环把样例A过了,结果一个点结果错误,另九个点时间超限……(早知道我不写了)
第四道题:剩下20分钟,呵呵呵,开手速吧……15分钟竟然写过了!?没有!如果单单是有传送门的话我就A了,但是输入要求非常莫名其妙,竟然不输入行数和列数?还有折叠空间?一生气,果断卡测评机。
我过了8个点,160分,感觉自己要跪了,结果问问发现200+的有三个我们学校的大神,然后140+的有7个,其中2个新初二的,2个新初一的,还有一个新高一的,一个新初三的。80+的有四个大犇,剩下的14+个全是0分、20分、40分左右的。题很水啊~~是不是失手了??想我这样的弱鸡都能对8个点,醉了……
下面来一些具体分析~~
敌人
考试做法:跟团伙貌似没有任何区别,单纯并查集就有5个点了。
正解做法:用SIZE数组维护树的规模,其它没难度……
【代码】
#include<iostream>
using namespace std;
int n,m,a,b,pre[300101],ans;
int tmp[300101];
bool vis[300101];
int ch;
int find(int x)//找i节点的指针指向的节点编号
{
int t=x;
if(pre[t]!=t) pre[t]=find(pre[t]);
return pre[t];
}
void join(int x,int y)//连边
{
int tx=find(x),ty=find(y);
pre[tx]=ty;
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) pre[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%d",&ch);
if(ch==1)
{
scanf("%d%d",&a,&b);
if(find(a)==find(b)) printf("Y\n");//如果指针一样那么就是朋友
else
{
printf("N\n");//输出不是
if(!tmp[a]) tmp[a]=b;//逆向储存
else join(tmp[a],b);
if(!tmp[b]) tmp[b]=a;
else join(tmp[b],a);
}
}
else
{
scanf("%d",&a);
for(int j=1;j<=n;j++) if(find(a)==find(j)&&a!=j) ans++;//这里需要优化,否则时间超限
printf("%d\n",ans);
ans=0;
}
}
}
国际象棋
没难度,只不过一定要用BFS!!
我的代码:
#include<iostream>
#include<cstring>
using namespace std;
inline int read(){
int x=0,sig=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
}
char map[1001][1001];//u行v列
int a[1001][1001],ans=0,m,n;
void res(int u,int v,int i,int j)
{
int t=a[u][v];
if(u==i&&v==j) ans=t;
t++;//挨个搜
if(u+2<=n&&v+1<=n&&map[u+2][v+1]!=‘#‘&&a[u+2][v+1]>t)
{
a[u+2][v+1]=t;
res(u+2,v+1,i,j);
}
if(u+2<=n&&v-1>0&&map[u+2][v-1]!=‘#‘&&a[u+2][v-1]>t)
{
a[u+2][v-1]=t;
res(u+2,v-1,i,j);
}
if(u-2>0&&v+1<=n&&map[u-2][v+1]!=‘#‘&&a[u-2][v+1]>t)
{
a[u-2][v+1]=t;
res(u-2,v+1,i,j);
}
if(u-2>0&&v-1>0&&map[u-2][v-1]!=‘#‘&&a[u-2][v-1]>t)
{
a[u-2][v-1]=t;
res(u-2,v-1,i,j);
}
if(v+2<=n&&u+1<=n&&map[u+1][v+2]!=‘#‘&&a[u+1][v+2]>t)
{
a[u+1][v+2]=t;
res(u+1,v+2,i,j);
}
if(v+2<=n&&u-1>0&&map[u-1][v+2]!=‘#‘&&a[u-1][v+2]>t)
{
a[u-1][v+2]=t;
res(u-1,v+2,i,j);
}
if(v-2>0&&u+1<=n&&map[u+1][v-2]!=‘#‘&&a[u+1][v-2]>t)
{
a[u+1][v-2]=t;
res(u+1,v-2,i,j);
}
if(v-2>0&&u-1>0&&map[u-1][v-2]!=‘#‘&&a[u-1][v-2]>t)
{
a[u-1][v-2]=t;
res(u-1,v-2,i,j);
}
}
int main()
{
int startx=1,starty=1,endx,endy,c,b;
n=read(),m=read();
memset(a,1,sizeof(a));
memset(map,‘.‘,sizeof(map));
endx=n;endy=n;
map[1][1]=‘@‘;
map[n][n]=‘*‘;
for(int i=0;i<m;i++)
{
c=read(),b=read();
map[c][b]=‘#‘;
}
a[startx][starty]=0;
m=n;
res(startx,starty,endx,endy);
write(ans);
}
我的正解:
#include<iostream>
#include<queue>
using namespace std;
inline int read()
{
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c==‘-‘)f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
return x*f;
}
int n,m,e[1001][1001],cur[1001][1001];
int b[8][2]={{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
bool vis[1001][1001];
int bfs()
{
queue<int>Q;
Q.push(10001);
vis[1][1]=1;
while(Q.size())
{
int x=Q.front()/10000;
int y=Q.front()%10000;
Q.pop();
for(int i=0;i<8;i++)
{
int xt=x+b[i][0],yt=y+b[i][1];
if(xt>n || xt<1 || yt>n || yt<1) continue;
if(e[xt][yt]!=-1 && !vis[xt][yt]){
cur[xt][yt]=cur[x][y]+1;
if(xt==n && yt==n) return cur[xt][yt];
vis[xt][yt]=1;
Q.push(xt*10000+yt);
}
}
}
return -1;
}
int main()
{
int a,b;
n=read(),m=read();
for(int i=0;i<m;i++)
{
a=read(),b=read();
e[a][b]=-1;
}
printf("%d",bfs());
}
地铁网络:
辛辛苦苦打了一个暴力,结果没过一个点 QAQ
#include<iostream>
#include<cstring>
#include<cmath>
inline int read(){
int x=0,sig=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
}
using namespace std;
char str[250000][16],str2[200000][16],strstra[16],strans[250000][16];
int e[2500][2500],n,m,q,xy[250000][2],ans;// 3750000
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>str[i];
xy[i][0]=read();
xy[i][1]=read();
}
q=read();
memset(e,999999,sizeof(e));
for(int i=0;i<q;i++)
{
m=read();;
for(int j=0;j<m;j++)
{
cin>>str2[j];
for(int k=j-1;k>=0;k--)
{
int f,o;
for(int p=0;p<n;p++)
{
if(strcmp(str2[k],str[p])==0) f=p;
else if(strcmp(str2[j],str[p])==0) o=p;
}
e[f][o]=1;
e[o][f]=1;
}
}
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j) e[i][j]=0;
else if(e[i][j]==1) e[i][j]=abs(xy[i][0]-xy[j][0])+abs(xy[i][1]-xy[j][1]);
}
cin>>m>>strstra;
int r=(m-3)*2000;
int f;
for(int p=0;p<n;p++)
if(strcmp(strstra,str[p])==0) {f=p;break;}
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
int num;
for(int i=0;i<n;i++)
if(e[f][i]>r&&e[f][i]<=r+2000)
{
for(int p=0;p<n;p++)
if(strcmp(str[i],str[p])==0) num=p;
strcpy(strans[ans++],str[num]);
}
for(int i=0;i<ans-1;i++)
for(int j=i+1;j<ans;j++)
{
if(strcmp(strans[i],strans[j])>0)
{
strcpy(strstra,strans[i]);
strcpy(strans[i],strans[j]);
strcpy(strans[j],strstra);
}
}
for(int i=0;i<ans-1;i++)
{
int len=strlen(strans[i]);
for(int j=0;j<len;j++)
putchar(strans[i][j]);
printf(" ");
}
int len=strlen(strans[ans-1]);
for(int j=0;j<len;j++)
putchar(strans[ans-1][j]);
}
思考题:传送门
这里给出我的这题的不包含变态输入的AC代码,大家可以尝试更改
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
#define MAXN 205
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
typedef struct _Node
{
int x, y;
int step;
}Node;
Node p[MAXN], start;
char Map[MAXN][MAXN];
int v[MAXN][MAXN];
int n, m, res, cas;
int Sx, Sy, Ex, Ey, k;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
priority_queue <Node> pq;
int kdd;
bool operator < (Node a, Node b)
{
return a.step > b.step;
}
bool check(int x, int y)
{
return x>=0 && y>=0 && x<n && y<m && Map[x][y]!=‘#‘ && !v[x][y];
}
int BFS()
{
Node cur;
int px, py, xx, yy, cstep;
while(!pq.empty()) {
cur = pq.top(), pq.pop();
px = cur.x, py = cur.y, cstep = cur.step;
for(int i=0; i<4; i++) {
xx = px + dx[i], yy = py + dy[i];
if(check(xx, yy)) {
if(xx == Ex && yy == Ey) return cstep+1;
if(Map[xx][yy] == ‘T‘) {
for(int j=0; j<k; j++)
{
int fx = p[j].x, fy = p[j].y;
if(!v[fx][fy]) {
cur.x = fx, cur.y = fy;
cur.step = cstep + 2;
pq.push(cur);
}
}
}else if(Map[xx][yy] == ‘.‘) {
cur.x = xx, cur.y = yy;
cur.step = cstep + 1;
pq.push(cur);
}
v[xx][yy] = 1;
}
}
}
return -1;
}
int main()
{
cin>>n>>m;
k = 0;
for(int i=0; i<n; i++)
{
scanf("%s", Map[i]);
for(int j=0; j<m; j++)
{
if(Map[i][j] == ‘T‘)
{
p[k].x = i, p[k].y = j;
p[k++].step =0;
}
}
}
cin>>Sx>>Sy>>Ex>>Ey;
Sx--,Sy--,Ex--,Ey--;
RST(v);
v[Sx][Sy] = 1;
while(!pq.empty()) pq.pop();
start.x = Sx, start.y = Sy, start.step = 0;
pq.push(start);
res = BFS();
printf("%d\n", res);
}
原文:http://www.cnblogs.com/wxjor/p/5721939.html