Decode(ZOJ 3636)
给定k个长度为n的01向量以及异或运算,就得到了一个集合S($$ x \in S $$当且仅当从k个向量中取若干个异或起来可以得到x)。再给定m个询问,每个询问包含一个01向量,要求你在容错位最多为3的前提下找一个离该向量最近并属于S的01向量。如果有多个,输出字典序最小的。
想想如果给你一个01向量,让你判断它在不在S里这是很容易办到的。具体做法就是$$x_i$$表示那k个向量的取和不取的状态,然后得到一个异或方程,高斯消元就可以了。但是注意到这里n只有30,所以那么多向量是没有用的,直接把给的向量消成上三角矩阵,得到其中有用的若干个,就可以在$$O(n)$$的复杂度内判断一个码在不在集合S内了。又由于每个码只允许改3个位,只需暴力枚举改哪三个位再用上面的方法判断就行了。
#include
#include
#include
#include
#include
#include
#include
Alice's present(ZOJ 3633)
给定一个序列$$a_i$$,每次询问一个区间内,从右往左看,第一个重复的是谁
设next[i]表示a[next[i]] = a[i]且next[i] > i的最小值,那么询问按左端点排序以后,按其降序扫过去,然后每个询问(l, r)相当于问next[i] ≤ r 的值里最大的i所对应的a[i]是多少。这个显然可以树状数组求最值,就是按next[i]为下标建立树状数组然后blablabla...其实sort后可以$$O(n)$$地用单调队列搞,按类似的思路做也不难实现。
#include
#include
#include
#include
#include
#include
#include
Bounty Hunter(ZOJ 3634)
有一只Bounty Hunter,他按顺序从城市1跑到城市n,在每个城市进行两个操作:买攻击力和做任务。在城市i,每点攻击力要花费$$a_i$$块钱。买完攻击力以后做任务时可以获得$$atp * b_i$$(atp为当时的攻击力)的钱,问最后Bounty Hunter最多能获得多少钱。
设mow[i]表示如果你在进入第i个城市之前,有1块钱,那么在之后最多能变成多少块钱,apw[i]表示如果你在进入第i个城市之前,有1点攻击力,那么在之后最多会演化成多少块钱,然后转移就很显然了,不懂就看代码吧...就像dp一样的思路,唯一需要说明的一点大概是:因为这个转换关系都是常数倍的关系,所以这些获利都可以分开考虑,最后叠加。
#include
#include
#include
#include
#include
#include
#include
Information Sharing(ZOJ 3641)
给定每个人身上所带的消息以及若干个集合的合并操作,每次动态问某个人所属的集合中,拥有的信息有哪一些。
因为保证信息数不超过1000,那么1000 * n bitset Disjoint Set暴力合并随便搞。
其实把信息数的条件去掉也可以做的,但是要保证答案size不超过多大或者直接换成输出拥有的信息的数目。这样子的做法大致是两个集合合并的时候,Disjoint Set依然是路径压缩式合并,但是set的合并要从set.size()比较小的那个逐个暴力插入到大的set里面。因为每个人最多只带10个信息,这样可以保证最后复杂度不超过$$O(10n log^2 10n)$$。
#include
#include
#include
#include
#include
..
:Amazed:
仰慕写解题报告的学长
BG吧!
继承shi哥意志继续操刀月赛题解的MJ桑~
手算了两个小时G最后剪枝错了没搞出来的表示泪奔。。。
orz
Bounty Hunter(ZOJ 3634)这题,不知道以下想法是否可行:
因为每次选择增加攻击力,对之前的状态都没影响,而是对之后的状态有影响,那就将对后面的影响考虑进来,后面全部的bi相加为sum,当前有的钱为money,可知在当前城市若增加攻击力,对后面的影响为money / ai * sum,那我们只要判断ai和sum大大小关系就可以决定在当前城市是否增加攻击力。还有一点,如果选择增加攻击力,那肯定是把钱全部用来增加攻击力,然后再换钱。
我想了两种方法,一种和解题报告的相似,一种就是上面描述的。我自己出的20多组数据答案都一样,可上面描述的方法就是Wa,也wa了20几次了
你要考虑到后面加的钱还可以重复利用。也就是说那些多出来的钱还要用来换新的攻击力的。
这个我有考虑,因为前面增加的攻击力不会减少,那么对后面的影响可以提前算出。当每次决策时,就用全部的钱减去前面的攻击力和钱对后面的影响,就得到当前用的钱,然后判断要不要买攻击力,要的话又继续算出对后面的影响。额,感觉说不清楚,能不能发一些数据到我邮箱:353230424@qq.com?
ZOJ数据是必须保密的…
其实我感觉你这个和我的思路应该差不多的啊。你要算出有多少影响,就必须考虑到钱怎么花才最好。这本身就要一个贪心的过程…
那悲剧了,应该也不是精度问题。咳,自己出数据对拍吧…
换个latex插件吧。这个看上去难看死了。
居然还是图片……
我觉得这个除了有点下沉以外还好啊,你的那个在firefox下是很漂亮,但是在windows默认设置的chrome里那些字体都发虚…图片不容易出这个问题= =|||
ZOJ 3634 这题数据有点问题?
int main(){
// freopen(“e:\in.txt”,”r”,stdin);
while(scanf(“%d%lf%lf”,&n,&X,&Y)!=EOF){
for(i=1;i=1;i–){
double k=(b[i+1]/x[i]+y[i]*a[i+1]/x[i]-a[i+1]);
double b1=a[i+1];
if(k<0) a[i]=b1;
else a[i]=k+b1;
b[i]=y[i]*a[i+1]+b[i+1];
if(i==n&&a[i]!=max((double)1,y[n]/x[n])) while(1){}
//这句话本来用来检测一下我代码初始化的问题,应该没什么影响,但加上去AC,不加会WA,这个。。。搞不懂了
}
printf("%.2lfn",X*a[1]+Y*b[1]);
}
return 0;
}
你的代码太不完整了…. 而且这是什么… “for(i=1;i=1;i–){”
这样我没法判断是哪边的问题
哦,这里格式好像有问题
这是AC代码的链接
http://acm.hust.edu.cn:8080/judge/contest/viewSource.action?id=668944
WA代码的链接
http://acm.hust.edu.cn:8080/judge/contest/viewSource.action?id=668940
两份代码就差了刚刚那一句
if(i==n&&a[i]!=max((double)1,y[n]/x[n])) while(1){}
看一下吧,谢谢
同学, 很抱歉地通知您, 你的代码在我本机跑, 不加O2是通过的.
加了O2, 你的某组case和答案差0.01.
大概是除法造成的精度损失比较大, 而我们又有0.005附近的数据, 所以跪了.
我试了下, 改成long double 也无济于事…
而你加了那句话以后, 那部分代码有死循环, O2就不作优化了… 于是就过了.
饿,好吧我错了,谢谢啦