欢乐赛解题报告

~~一场不欢乐的欢乐赛

时间分配::T1做的时候还可以,大约三十分钟写了个深搜(鬼知道我为啥不用广搜,大概是因为快半个月没写了)写完后去研究第二题,刚开始以为是贪心,很快写了出来,但是自己推了一会举出了反例。于是自己想了很多方法,但是都是基于贪心,写了一个多小时,写炸了,没办法又改成了贪心。第三题并不会,然后搜索大法过了一个点,(输出-1也是一个点)

整体感觉::还是太弱,T1是会的,但是还是没做对,大概是独立做题少的缘故吧,平常做题都没有思考太多时间。T2贪心T3暴力,貌似自己啥都不会。到现在第三题好像快要放弃了,题解一点也,看不懂。

题目解析::

T1::

水灾(sliker.cpp/c/pas) 1000MS  64MB

大雨应经下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。

CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。

CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。

求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。

----------------------------------------------------------------------------------------------------------------------

洪水的强化的强化版,关键处在于人在走第不同的步数时洪水的状态时不同的,在走相同步数时洪水的状态是相同的。通过这个我们可以先推导出人在走第n步时的洪水状态。之后

广搜,条件是下一步要走到的位置洪水没有覆盖且没走过且是‘。’的点。

第一遍做时用的深搜,半个月没写广搜了,思维惯性,T了6个点

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

char map[1500][61][61];

bool hsvisited[61][61];

bool renvisited[61][61];

int xgo[4]={1,-1,0,0};

int ygo[4]={0,0,1,-1};

int nowx;int nowy;int fx;int fy;int n;int m;int ans=0x7ffffff;

void dfs(int step,int x,int y)

{

//if(map[step][x][y]==‘*‘)return;//合理化剪枝 算了放循环里吧

if(x==fx&&y==fy)

{

ans=min(step,ans);

return;

}

if(step>ans)return; //最优化剪枝

for(int i=0;i<4;i++)

{

int xn=x+xgo[i];

int yn=y+ygo[i];

if(!renvisited[xn][yn]&&(map[step+1][xn][yn]==‘.‘||map[step+1][xn][yn]==‘D‘))

{

renvisited[xn][yn]=true;

dfs(step+1,xn,yn);

renvisited[xn][yn]=false;

}

}

}

int main()

{

freopen("sliker.in","r",stdin);

freopen("sliker.out","w",stdout);

cin>>n>>m;

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

cin>>map[0][i][j];

if(map[0][i][j]==‘S‘)

{

nowx=i;

nowy=j;

map[0][i][j]=‘.‘;

renvisited[i][j]=true;

}

if(map[0][i][j]==‘D‘)

{

fx=i;fy=j;

}

}

for(int z=1;z<=1300;z++)     //离线处理 //jiduanqingkuangbukaolvle chutiren meinamewuliao

{

//bool flag=false;

memset(hsvisited,0,sizeof(hsvisited));

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

if(map[z-1][i][j]==‘*‘)

{

for(int op=0;op<4;op++)

{

int xn=i+xgo[op];

int yn=j+ygo[op];

if(map[z-1][xn][yn]==‘.‘)

{

hsvisited[xn][yn]=1;

//flag=true;     这个不能加

}

}

}

map[z][i][j]=map[z-1][i][j];

}

//if(!flag)break;

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

if(hsvisited[i][j])

map[z][i][j]=‘*‘;

}

}

dfs(0,nowx,nowy);

if(ans==0x7ffffff)

printf("ORZ hzwer!!!");

else

printf("%d",ans);

fclose(stdin);

fclose(stdout);

return 0;

}

/*

3 3

D.*

...

.S.

*/

/*

3 3

D.*

...

..S

*/

/*

3 6

D...*.

.X.X..

....S.

3 3

D..

...

..S

*/

第二遍做的时候在原来基础上改成了广搜,就可以了

#include<queue>

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

struct note

{int x;int y;int step;};

char map[1500][61][61];

bool hsvisited[61][61];

bool renvisited[61][61];

int xgo[4]={1,-1,0,0};

int ygo[4]={0,0,1,-1};

int nowx;int nowy;int fx;int fy;int n;int m;

queue<note>q;

int main()

{

freopen("sliker.in","r",stdin);

freopen("sliker.out","w",stdout);

cin>>n>>m;

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

cin>>map[0][i][j];

if(map[0][i][j]==‘S‘)

{

nowx=i;

nowy=j;

map[0][i][j]=‘.‘;

renvisited[i][j]=true;

}

if(map[0][i][j]==‘D‘)

{

fx=i;fy=j;

}

}

for(int z=1;z<=1300;z++)     //离线处理 //jiduanqingkuangbukaolvle chutiren meinamewuliao

{

memset(hsvisited,0,sizeof(hsvisited));

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

if(map[z-1][i][j]==‘*‘)

{

for(int op=0;op<4;op++)

{

int xn=i+xgo[op];

int yn=j+ygo[op];

if(map[z-1][xn][yn]==‘.‘)

{

hsvisited[xn][yn]=1;

}

}

}

map[z][i][j]=map[z-1][i][j];

}

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

{

if(hsvisited[i][j])

map[z][i][j]=‘*‘;

}

}

note zz;

zz.x=nowx;

zz.y=nowy;

zz.step=0;

q.push(zz);

while(!q.empty())

{

note op=q.front();

q.pop();

for(int i=0;i<4;i++)

{

int xn=op.x+xgo[i];

int yn=op.y+ygo[i];

int s=op.step;

if((map[s+1][xn][yn]==‘.‘||map[s+1][xn][yn]==‘D‘)&&!renvisited[xn][yn])

{

renvisited[xn][yn]=1;

note iq;

iq.x=xn;

iq.y=yn;

iq.step=s+1;

if(xn==fx&&yn==fy)

{

printf("%d",iq.step);

return 0;

}

q.push(iq);

}

}

}

printf("ORZ hzwer!!!");

fclose(stdin);

fclose(stdout);

return 0;

}

T2某种数列问题  (jx.cpp/c/pas) 1000MS 256MB

众所周知,chenzeyu97有无数的妹子(阿掉!>_<),而且他还有很多恶趣味的问题,继上次纠结于一排妹子的排法以后,今天他有非(chi)常(bao)认(cheng)真(zhe)去研究一个奇怪的问题。有一堆他的妹子站成一排,然后对于每个妹子有一个美丽度,当然美丽度越大越好,chenzeyu97妹子很多,但是质量上不容乐观,经常出现很多美丽度为负数的妹子(喜闻乐见),chenzeyu97希望从一排妹子里找出3队连续的妹子,使她们的美丽度和最大。注意,一个妹子不能被编入多个队伍而且一定要拿出三队,不然czy会闲着没事做~。

简单滴说就是:

给定一个数列,从中找到3个无交集的连续子数列使其和最大。

【输入文件】

第一行一个数n,表示数列长度。

接下来有n行,每行一个数,第i行为第i个数。

【输出文件】

仅有一个数,表示最大和。

方法::假如在做单一的最大子段和的问题时用的dp解法而不是贪心,做这个题就会容易得多。毕竟只是多了一个条件。

状态::f【i】【j】【flag】表示到第i个数选了j段妹子并且当前数是否要选的状态

#include<cstdio>

#include<algorithm>

using namespace std;

int note[1000001];

int dp[4][1000001][2];

int read()

{

int f=1;

int num=0;

char c=getchar();

while(c<‘0‘||c>‘9‘){

if(c==‘-‘)f=-1;

c=getchar();

}

while(c>=‘0‘&&c<=‘9‘)

{

num*=10;

num+=c-‘0‘;

c=getchar();

}

return f*num;

}

int main()

{

freopen("jx.in","r",stdin);

freopen("jx.out","w",stdout);

int n=read();

for(int i=1;i<=n;i++)

{

note[i]=read();

}

for(int i=1;i<=n;i++)

{

for(int j=1;j<=3;j++)

{

dp[j][i][0]=max(dp[j][i-1][0],dp[j][i-1][1]);

/*既然当前的的不拿,最大值就和当前无关,只需要判断前一步的最大值*/

dp[j][i][1]=max(dp[j][i-1][1]+note[i],max(dp[j][i][1],dp[j-1][i-1][0]+note[i]));

/*当前的若要拿的话   分两种情况*/

/*与上一个连着  单成一个*/

/*但是如果这两种情况都小于0时还不如不选*/

}

}

printf("%d",max(dp[3][n][1],dp[3][n][0]));

return 0;

}

但是,在考试时这个题想不出来dp的方法,就跑了三遍贪心,竟然过了6个点

#include<cstdio>//本来打算用一种贪心+排序。。。算了,贪心三遍吧 我也知道不对万一碰上呢

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int shuru[1000001];

bool visited[1000001];

int ans=0;

int n,top=0;

int read()

{

int f=1;

int now=0;

char c=getchar();

while(c<‘0‘||c>‘9‘)

{

if(c==‘-‘)f=-1;

c=getchar();

}

while(c>=‘0‘&&c<=‘9‘)

{

now*=10;

now+=c-‘0‘;

c=getchar();

}

return f*now;

}

int main()

{

freopen("jx.in","r",stdin);

freopen("jx.out","w",stdout);

n=read();

for(int i=1;i<=n;i++)

shuru[i]=read();

for(int z=1;z<=3;z++)

{

int su=-9999999;

int wei;

int ge;

int op=0;

int tot=0;

for(int i=1;i<=n;i++)

{

if(visited[i])

{

op=0;

tot=0;

continue;

}

if(op<0)

{

op=0;

tot=0;

}

op+=shuru[i];

tot++;

if(op>su)

{

su=op;

wei=i;

ge=tot;

}

}

ans+=su;

for(int i=wei-ge+1;i<=wei;i++)

visited[i]=1;

}

printf("%d",ans);

fclose(stdin);

fclose(stdout);

return 0;

}

T3

密码锁 1000MS 512MB

Input: password.in

Output: password.out

【题目描述】

hzwer有一把密码锁,由N个开关组成。一开始的时候,所有开关都是关上的。当且仅当开关x1,x2,x3,...xk为开,其他开关为关时,密码锁才会打开。

他可以进行M种的操作,每种操作有一个size[i],表示,假如他选择了第i种的操作的话,他可以任意选择连续的size[i]个格子,把它们全部取反。(注意,由于黄金大神非常的神,所以操作次数可以无限>_<)

本来这是一个无关紧要的问题,但是,黄金大神不小心他的钱丢进去了,没有的钱他哪里能逃过被chenzeyu97 NTR的命运?>_<  于是,他为了虐爆czy,也为了去泡更多的妹子,决定打开这把锁。但是他那么神的人根本不屑这种”水题”。于是,他找到了你。

你的任务很简单,求出最少需要多少步才能打开密码锁,或者如果无解的话,请输出-1。

【输入格式】

第1行,三个正整数N,K,M,如题目所述。

第2行,K个正整数,表示开关x1,x2,x3..xk必须为开,保证x两两不同。

第三行,M个正整数,表示size[i],size[]可能有重复元素。

【输出格式】

输出答案,无解输出-1。

方法::

时间: 2024-10-26 01:32:20

欢乐赛解题报告的相关文章

CH Round #56 - 国庆节欢乐赛解题报告

最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树,其中一些树上结有能够产生能量的魔力水果.已知每个水果的位置(Xi,Yi)以及它能提供的能量Ci.然而,魔幻森林在某些时候会发生变化:(1) 有两行树交换了位置.(2) 有两列树交换了位置.当然,树上结有的水果也跟随着树一起移动.不过,只有当两行(列)包含的魔力水果数都大于0,或者两行(列)都没有魔

20161027模拟赛解题报告

20161027模拟赛解题报告 By shenben T1 数学题 模拟即可. 注意开long long T2 技巧题 图片为本题第一张图.(无奈,图传不上来) 首先第一问图中的“Y 字形”的数量,这么简单,在此不细讲. 详见代码 O(n)累加一下就好了 主要说说第二问怎么搞 预处理 每个点分别与其他那些点相连 权值为第1,2,3大(若没有2,3大,就忽略).记录一下权值与对应的点的标号.目的是方便下面的判断. 枚举入度>=3的点,即点B(有多个) 再枚举点B相连的D点(不是点A,C). Ste

20161026模拟赛解题报告

20161026模拟赛解题报告 By shenben T1 按照题目说的模拟即可 但这题有一个神坑:当25个字母都已经一一对应完毕后,剩下的两个字母默认对应. T2 所有的逆序对之间都会连边,求最大独立点集. 表面上是个图论题,其实是个LIS O(nlogn)求最长上升子序列的长度即可AC T3 第一次手贱,用链表存边,这是一个稠密图啊!!应该用邻接矩阵啊. 明明可以用floyed跑,非要dfs乱搞.结果10分.玩砸了吧. 最后只改到了40分. 网上的题解(没看懂): 首先这是一个神奇的图,叫做

CSU-ACM2014年校队选拔赛指导赛解题报告

•Problem A  CSU 1065                               贪心 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1000010; 6 struct Node{ 7 int a,b; 8 bool operator < (const Node& rhs)

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

20161109模拟赛解题报告

2016-11-09试题解题报告 By shenben 本解题报告解析均为100分解题思路. T1 模拟即可. 我怕极限数据5000(n,m)*100000(k). 如果用二维数组.空间勉强撑住,时间上够呛. 因此用2个一位数组分别代表行和列. 这样每次修改是O(1)的. 查询是O(nm)(只查询一次) 总时间复杂度:O(nmk) T2 搜索 一开始想偏了. 倒着由“a”往前推.结果小样例过了,大样例差太多. 于是另辟蹊径. 观察到数据范围很小. 直接枚举答案序列不就好了. 对于每个序列再判断一

2014牡丹江网络赛解题报告

The 2014 ACM-ICPC Asia Mudanjiang Regional First Round 题目链接 A题解题报告 B题解题报告 C题解题报告 D题解题报告 E题解题报告 F题解题报告 G题(未完成) H题解题报告 I题解题报告 J题解题报告

2014哈商大ICPC/ACM校赛解题报告

被debug邀请去參加校赛,哎,被虐..我对不起工大.. 由于本人不搞ACM,算法处于HelloWorld水准.. 虽然题目除了鸟不拉屎星人之外都非常水,但我能做到这个程度,全然是超水平发挥了.. 数据:点此下载 ============================================================== a:逆序数组+删除特定元素 题目: 小伙伴们好像非常多没接触过ICPC,那先来一道水题尝尝鲜,给出 一个数组,和一个特征值.将这个数组中特征值值删除后逆序输出.

NOI 2015 滞后赛解题报告

报同步赛的时候出了些意外.于是仅仅能做一做"滞后赛"了2333 DAY1 T1离线+离散化搞,对于相等的部分直接并查集,不等部分查看是否在同一并查集中就可以,code: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int t,n; int father[200001]; struct hp{ i