今天是第一天来中山,有点小期待啊,我来说一下吧,这次考试,我考的一般,但是我觉得吗,自己差的不是一点半点啊,所以QAQ,我要努力训练,哈哈哈哈。
首先我来看一下这次考试的题目吧、
T1.水叮当的舞步
Description
水叮当得到了一块五颜六色的格子形地毯作为生日礼物,更加特别的是,地毯上格子的颜色还能随着踩踏而改变。
为了讨好她的偶像虹猫,水叮当决定在地毯上跳一支轻盈的舞来卖萌~~~
地毯上的格子有N行N列,每个格子用一个0~5之间的数字代表它的颜色。
水叮当可以随意选择一个0~5之间的颜色,然后轻轻地跳动一步,地毯左上角的格子所在的联通块里的所有格子就会变成她选择的那种颜色。这里连通定义为:两个格子有公共边,并且颜色相同。
由于水叮当是施展轻功来跳舞的,为了不消耗过多的真气,她想知道最少要多少步才能把所有格子的颜色变成一样的。
Input
每个测试点包含多组数据。
每组数据的第一行是一个整数N,表示地摊上的格子有N行N列。
接下来一个N*N的矩阵,矩阵中的每个数都在0~5之间,描述了每个格子的颜色。
N=0代表输入的结束。
Output
对于每组数据,输出一个整数,表示最少步数。
Sample Input
2 0 0 0 0 3 0 1 2 1 1 2 2 2 1 0
Sample Output
0 3
Data Constraint
对于30%的数据,N<=5
对于50%的数据,N<=6
对于70%的数据,N<=7
对于100%的数据,N<=8,每个测试点不多于20组数据。
好的,这就是第一题的题目,首先我来讲一讲我的心路历程,我一开始并没有看到(左上角)这三个字,一直在想——这怎么爆搜啊,每个点枚举一遍QAQ??,那岂不是慢到飞起。知道某些原因(我是不会说是别人告诉我的QAQ),我才发现。其实最主要的是这一组数据
3
0 2 0
1 0 0
1 0 0
标答是3,然而我怎么看都是2,所以我再读了一遍(别问我标答从何而来),就发现了左上角QAQ,之后又花了我很长的差不多30多秒想到了迭代加深搜索,然后我的思路就截止了。
来来来考场代码贴一份
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-')
{
f=-1;
}
c=getchar();
}
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int a[9][9][101];
int n;
inline void scsc(int t)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<a[i][j][t]<<' ';
}
cout<<endl;
}
}
inline bool judge(int ti)
{
int cc=a[1][1][ti];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j][ti]!=cc)
{
return false;
}
}
}
return true;
}
int ans;
int xc[5]={0,1,-1,0,0};
int yc[5]={0,0,0,1,-1};
struct node
{
int x,y;
};
inline void change(int x,int y,int ti,int col)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j][ti]=a[i][j][ti-1];
}
}
int cs=a[x][y][ti];
queue<node> q;
q.push((node){x,y});
while(!q.empty())
{
node t=q.front();
q.pop();
a[t.x][t.y][ti]=col;
for(int i=1;i<=4;i++)
{
int xx=t.x+xc[i],yy=t.y+yc[i];
if(a[xx][yy][ti]==cs)
{
q.push((node){xx,yy});
}
}
}
}
void dfs(int step,int ti,int p)
{
if(judge(ti-1))
{
ans=p;
return;
}
if(step==p)
{
return;
}
for(int i=0;i<=5;i++)
{
if(i!=a[1][1][ti-1])
{
change(1,1,ti,i);
dfs(step+1,ti+1,p);
}
}
}
signed main()
{
while(1)
{
memset(a,-1,sizeof(a));
n=read();
ans=0x7ffffff;
if(n==0)
{
break;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j][0]=read();
}
}
int aa=0;
while(aa<=100)
{
dfs(0,1,aa);
if(ans!=0x7ffffff)
{
break;
}
aa++;
}
printf("%lld\n",ans);
}
return 0;
}
/*
5
3 0 3 0 0
5 0 2 5 5
4 3 5 3 0
2 4 3 4 4
4 4 0 0 4
*/
开始学起zxh来???
正解在下一篇博客,之后我就一篇考场,一篇正解了。
T2. Vani和Cl2捉迷藏
(第一眼看的像镍化钒与氯气QAQ应该是认错了吧)
Description
vani和cl2在一片树林里捉迷藏……
这片树林里有N座房子,M条有向道路,组成了一张有向无环图。
树林里的树非常茂密,足以遮挡视线,但是沿着道路望去,却是视野开阔。如果从房子A沿着路走下去能够到达B,那么在A和B里的人是能够相互望见的。
现在cl2要在这N座房子里选择K座作为藏身点,同时vani也专挑cl2作为藏身点的房子进去寻找,为了避免被vani看见,cl2要求这K个藏身点的任意两个之间都没有路径相连。
为了让vani更难找到自己,cl2想知道最多能选出多少个藏身点?
Input
第一行两个整数N,M。
接下来M行每行两个整数x、y,表示一条从x到y的有向道路。
Output
一个整数K,表示最多能选取的藏身点个数。
Sample Input
4 4 1 2 3 2 3 4 4 2
Sample Output
2
Data Constraint
对于20% 的数据,N≤10,M<=20。
对于60% 的数据, N≤100,M<=1000。
对于100% 的数据,N≤200,M<=30000,1<=x,y<=N。
这一到题目我居然A了,自以为想出了二分图算法就美滋滋,(然而旁边的黄越大佬深搜广搜双管齐下,就有80,顿时觉得自己TCL了)
这道题一看连通性,那不就是Floyd吗,然后再求最小路径覆盖吗???
好吧话不多说上代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-')
{
f=-1;
}
c=getchar();
}
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int a[201][201],f[201],ans;
bool dis[201][201],bz[201];
inline bool find(int x)
{
for(int i=1;i<=a[x][0];i++)
{
if (!bz[a[x][i]])
{
bz[a[x][i]]=true;
if (!f[a[x][i]]||find(f[a[x][i]]))
{
f[a[x][i]]=x;
return true;
}
}
}
return false;
}
signed main()
{
int n=read(),m=read();
for(int i=1;i<=m;i++)
{
dis[read()][read()]=true;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dis[k][j]&&dis[i][k])
{
dis[i][j]=true;
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dis[i][j])
{
a[i][0]++;
a[i][a[i][0]]=j;
}
}
}
for(int i=1;i<=n;i++)
{
memset(bz,false,sizeof(bz));
if(find(i))
{
ans++;
}
}
printf("%d",n-ans);
return 0;
}
T3.粉刷匠
Description
赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= =
现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍。赫克托有K桶颜色各不相同的油漆,第i桶油漆恰好可以粉刷Ci根石柱,并且,C1+C2+C3…CK=N(即粉刷N根石柱正好用完所有的油漆)。长老为了刁难赫克托,要求相邻的石柱颜色不能相同。
喜欢思考的赫克托不仅没有立刻开始粉刷,反而开始琢磨一些奇怪的问题,比如,一共有多少种粉刷的方案?
为了让赫克托尽快开始粉刷,请你尽快告诉他答案。
Input
第一行一个正整数T,表示测试数据组数
对于每一组测试数据数据:
第1行:一个正整数K
第2行:K个正整数,表示第i桶油漆可以粉刷的石柱个数,Ci。
Output
对于每组输入数据,输出一行一个整数,表示粉刷的方案数mod 1000000007。
Sample Input
3 3 1 2 3 5 2 2 2 2 2 10 1 1 2 2 3 3 4 4 5 5
Sample Output
10 39480 85937576
Data Constraint
30% N≤10, T≤5
50% N≤15, T≤5
80% K≤15,Ci≤5,T≤500
100% K≤15,Ci≤6,T≤2000
(突然发现自己题目都不是图片)
好的,我来说一下自己的解题思路
好吧其实我这一道题没有做出来,我已开始想的方法过于暴力以至于最小的点都有可能过不了,所以干干脆脆的放弃了(干干脆脆好吃美味)
其实就是把所有的柱子进行枚举所以复杂度O( )(别告诉我说绝对能过一个点,我没写就是了)
好吧,第三题我就补贴代码了,就当我是0分把QAQ(虽说我就是0分,德玛西亚)
最后通牒 ( 感言)
这次的考试整体难度我觉得还适应,不至于想某些题一样连暴力都做不出来,啦啦啦,所以,正解待会儿再发。
心路完,正解见