NOIp2016 D2T3 愤怒的小鸟【搜索】(网上题解正解是状压)
没啥别的想法,感觉就是搜索,经过原点的抛物线已知两个点就可以求出解析式,在还没有被打下来的两个猪之间随意配对,确定解析式之后标记在这个抛物线下被打下来的猪。
猪也可以单独用一个抛物线打下来。
和之前写斗地主的搜索模式差不多,$TLE60pts$
就是要注意一下精度问题,$get$一个新点:浮点数的判等不能用$==$,可能会有精度误差,只差一点点的情况下可以认为他们是相等的,精度大概就取$EPS=1e-8$
bool dy(double a,double b)
{//浮点误差
return Abs(a-b)<EPS;
}
//暴搜 60pts
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define N 20
#define EPS 1e-8
double Abs(double a)
{
if(a>=0.0) return a;
return -a;
}
bool dy(double a,double b)
{//浮点误差
return Abs(a-b)<EPS;
}
int rd()
{
int f=,s=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){s=(s<<)+(s<<)+(c^);c=getchar();}
return f*s;
}
int n,m,ans;
struct node{
double x,y;
}pt[N];
bool vis[N];
int tmp[N],cnt;
void dfs(int k)//发射小鸟的次数
{
if(k>ans) return ;
for(int i=;i<=n;i++)
{
if(vis[i]) continue;
vis[i]=;
for(int j=i+;j<=n;j++)
{
if(vis[j]) continue;
double x1=pt[i].x,x2=pt[j].x,y1=pt[i].y,y2=pt[j].y;
double a=(y1*x2-y2*x1)/(x1*x2*x1-x1*x2*x2);
if(a>=) continue;//vis[j]=1要放在这个后面 否则不构成继续递归的条件也还是标记了
double b=(y1*x2*x2-y2*x1*x1)/(x1*x2*x2-x1*x1*x2);
//queue<int>Q;
//while(!Q.empty()) Q.pop();
cnt=;
vis[j]=;
for(int p=;p<=n;p++)
if(dy(pt[p].x*pt[p].x*a+pt[p].x*b,pt[p].y))
{
vis[p]=;
tmp[++cnt]=p;
//Q.push(p);
}
dfs(k+);
vis[j]=;
for(int i=;i<=cnt;i++)
vis[tmp[i]]=;
cnt=;
/*while(!Q.empty())
{
int u=Q.front();Q.pop();
vis[u]=0;
}*/
}
vis[i]=;
}
for(int i=;i<=n;i++)
if(!vis[i]) k++;
ans=min(ans,k);
return ;
}
int main()
{
int T=rd();
while(T--)
{
n=rd(),m=rd();
for(int i=;i<=n;i++)
scanf("%lf %lf",&pt[i].x,&pt[i].y),vis[i]=;
if(n==)
{
puts("");
continue;
}
if(n==)
{
/*
x1*x1*x2*a+x1*x2*b=y1*x2
x2*x2*x1*a+x2*x1*b=y2*x1
(x1*x1*x2-x1*x2*x2)a=y1*x2-y2*x1
x1*x2*(x1-x2)a=y1*x2-y2*x1
*/
if(((pt[].x*pt[].x*(pt[].x-pt[].x))*(pt[].y*pt[].x-pt[].y*pt[].x))<)
puts("");
else puts("");
continue;
}
if(m==||m==)
{
ans=n;
//for(int i=1;i<=n;i++)
// printf("%f %f %d\n",pt[i].x,pt[i].y,vis[i]);
dfs();
printf("%d\n",ans);
}
if(m==)
{
ans=((n+)/+);
dfs();
printf("%d\n",ans);
}
}
return ;
}
Code
然后,改用了以猪头作为...线索(?姑且这么叫着吧,找不到什么更好的词)
把抛物线和没有放抛物线的猪头存下来,每次遍历到猪头的时候就看这个猪头有没有在抛物线上,如果有就不用管他。没有就考虑把这个猪头和前面没有打下来的猪头放在一起看能否组成一个新的开口向下的抛物线,或者让他单着。
感觉每次把前面的猪头取出来放回去的操作改成链表的话,就很想$DLX$了呢。
这种写法可以过,但是我不会证复杂度什么的。
机房$dalao$说用$DLX$+迭代加深不能过....我...也很疑惑...
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define N 20
#define EPS 1e-8
double Abs(double a)
{
if(a>=0.0) return a;
return -a;
}
bool dy(double a,double b)
{//浮点误差
return Abs(a-b)<EPS;
}
int rd()
{
int f=,s=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){s=(s<<)+(s<<)+(c^);c=getchar();}
return f*s;
}
int n,m,ans;
struct node{
double x,y;
}pt[N]/*猪*/,pwx[N]/*抛物线*/;
int id[N];//单独的猪的标号
void dfs(int k,int u/*抛物线*/,int v/*单独的猪*/)
{
if(u+v>=ans) return ;
if(k>n)
{
ans=min(ans,u+v);
return ;
}
bool flag=;
for(int i=;i<=u;i++)
if(dy(pwx[i].x*pt[k].x*pt[k].x+pwx[i].y*pt[k].x,pt[k].y))
{
dfs(k+,u,v);
flag=;
break;
}
if(flag) return ;//如果已经可以被打掉,就不用管了
//否则就 要么和其它猪形成抛物线 要么自己单独
double x1=pt[k].x,y1=pt[k].y;
for(int i=;i<=v;i++)
{
double x2=pt[id[i]].x,y2=pt[id[i]].y;
if(dy(x1,x2)) continue;
double a=(y1*x2-y2*x1)/(x1*x2*x1-x1*x2*x2);
if(a>=) continue;
double b=(y1*x2*x2-y2*x1*x1)/(x1*x2*x2-x1*x1*x2);
pwx[u+].x=a,pwx[u+].y=b;
int tmp=id[i];
for(int j=i;j<v;j++)
id[j]=id[j+];
dfs(k+,u+,v-);
for(int j=v;j>i;j--)
id[j]=id[j-];
id[i]=tmp;
}
id[v+]=k;
dfs(k+,u,v+);
}
int main()
{
int T=rd();
while(T--)
{
n=rd(),m=rd();
for(int i=;i<=n;i++)
scanf("%lf %lf",&pt[i].x,&pt[i].y);
if(n==)
{
puts("");
continue;
}
if(n==)
{
if(((pt[].x*pt[].x*(pt[].x-pt[].x))*(pt[].y*pt[].x-pt[].y*pt[].x))<)
puts("");
else puts("");
continue;
}
ans=n;
dfs(,,);
printf("%d\n",ans);
}
return ;
}
Code
至于正解的什么状压,不如...放飞象征和平的鸽子?
NOIp2016 D2T3 愤怒的小鸟【搜索】(网上题解正解是状压)的更多相关文章
- NOIP2016 D2-T3 愤怒的小鸟
看了题解之后知道,是状压dp. 一.首先预处理一个$2^n$次方的fpow[]数组 fpow[]=; ;i<=;i++)fpow[i]=(fpow[i-]<<); 二.然后预处理一个 ...
- 【NOIP2016】愤怒的小鸟 搜索
题目描述 Kiana 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0,0)(0,0) 处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟,小 ...
- 计蒜客模拟赛D2T3 蒜头君救人:用bfs转移状压dp
题目链接:https://nanti.jisuanke.com/t/16444 题意: 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境 ...
- 【题解】P3959 宝藏 - 状压dp / dfs剪枝
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝 ...
- Bzoj 3813 奇数国 题解 数论+线段树+状压
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 748 Solved: 425[Submit][Status][Discuss] ...
- 洛谷P2831 愤怒的小鸟——贪心?状压DP
题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...
- 【状压DP】【P2831】【NOIP2016D2T3】愤怒的小鸟
传送门 Description Kiana 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 $(0,0)$ 处,每次 Kiana 可以用它向第一象限发射一 ...
- 【NOIP2017】宝藏 题解(状压DP)
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中 ...
- 分享网上搜到的Oracle中对判定条件where 1=1的正解
今天在网上找到了Oracle中对判定条件where 1=1的正解,粘贴出来和大家分享下 1=1 是永恒成立的,意思无条件的,也就是说在SQL语句里有没有这个1=1都可以. 这个1=1常用于应用程序根据 ...
随机推荐
- autoprefixer 处理css3的前缀
css3书写的时候,有时需要加上前缀,比如“-webkit-*.-moz-*”等等,但可能会写的不完整或者是写错,也很麻烦,那么autoprefixer可以处理这些. autoprefixer是一个后 ...
- Spring下的@Order和@Primary与javax.annotation-api下@Priority【Spring4.1后】等方法控制多实现的依赖注入(转)
@Order 可以作用在类.方法.属性. 影响加载顺序. 若不加,spring的加载顺序是随机的. @Primary 当注入bean冲突时,以@Primary定义的为准. @Order是控制配置类的加 ...
- dup和dup2函数简单使用
dup函数 头文件和函数原型: #include <unistd.h> int dup(int oldfd); dup函数是用来打开一个新的文件描述符,指向和oldfd同一个文件,共享文件 ...
- AcWing:167. 木棒(dfs + 剪枝)
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位. 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度. 请你设计一个程序,帮助乔 ...
- js获取键盘编码
原理:键盘上的按键都有各自的键码,通过这个键码可以来判断按下的是哪个键,下面函数可以获取键盘的键码,按下键盘按键就会在控制台打印出相应的键码 document.addEventListener(&qu ...
- 设置Linux自启服务以及优先级
一. 启动优先级 今天有一台服务器没有正常启动,原因是有一个服务没有启动起来,因为A服务需要B服务启动之后才能正常启动,所以需要调整A,B服务的启动顺序.在网上查找了一些资料,总结了一下,以备以后需要 ...
- 2016 ICPC 大连网络赛 部分题解
先讲1007,有m个人,n种石头,将n种石头分给m个人,每两个人之间要么是朋友关系,要么是敌人关系,朋友的话他们必须有一种相同颜色的石头,敌人的话他们必须所有石头的颜色都不相同.另外,一个人可以不拥有 ...
- PHP-异常-1
PHP 错误处理 在 PHP 中,默认的错误处理很简单.一条消息会被发送到浏览器,这条消息带有文件名.行号以及一条描述错误的消息. 在创建脚本和 web 应用程序时,错误处理是一个重要的部分.如果您的 ...
- 关于我&留言板
在下高一OIer一枚,就读于SC的一所发展中学(ruo)校 对二次元什么的,有着淡淡的喜爱 初三的时候入了古风的坑,想变得文艺一点,可爱一点 也会听歌,但听得不多(主要是听新歌比较随缘),范围窄(古风 ...
- 代码审计之seacms v6.54 前台Getshell 复现分析
1.环境: php5.5.38+apache+seacms v6.54 上一篇文章针对seacms v6.45 进行了分析,官方给出针对修复前台geishell提供的方法为增加: $order = ( ...