zoukankan      html  css  js  c++  java
  • 【CF698D】Limak and Shooting Points(DFS)

    点此看题面

    • 平面上有(k)个人和(n)个怪物,规定一个人一次只能向某个方向射死第一个怪物。
    • 求有多少怪物可能被射死。
    • (kle 7,nle10^3)

    暴力全排列+顺序指定

    对于一个怪物,我们直接枚举人的全排列。

    我们假设由第一个人射死了这个怪物,那么之后的人就要为他扫清障碍,方便起见规定之后的人从第一个人到这个怪物之间的第一个怪物开始依次扫清。

    然而,第二个人若想扫清第一个障碍,中间可能还会存在其他障碍,这相当于是一个递归的过程,就由第三个人开始为他先扫清障碍。

    具体实现中只要定义一个(Check(x))函数,并在此之外设立一个全局变量(nw)表示当前要让(nw)射死(x),然后递归调用就可以解决了。

    因为我们枚举了全排列,所以这样强定顺序是毫无问题的。

    最好现在一开始预处理出每个人和每个怪物之间所有的障碍怪物,能够提高代码效率。

    代码:(O(kn^2+nkcdot k!))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define K 7
    #define N 1000
    using namespace std;
    int k,n,id[K+5];vector<int> P[K+5][N+5];
    I int gcd(CI x,CI y) {return y?gcd(y,x%y):x;}
    struct P
    {
    	int x,y;I P(CI a=0,CI b=0):x(a),y(b){}
    	I long long L2() {return 1LL*x*x+1LL*y*y;}
    	I P S() {RI d=gcd(abs(x),abs(y))*(x?(x>0?1:-1):(y>0?1:-1));return P(x/d,y/d);}
    	I P operator - (Con P& o) Con {return P(x-o.x,y-o.y);}
    	I bool operator < (Con P& o) Con {return x^o.x?x<o.x:y<o.y;}
    	I bool operator == (Con P& o) Con {return x==o.x&&y==o.y;}
    }s[K+5],p[N+5];
    int nw,vis[N+5];I bool Check(CI x)//检验nw能否射死x
    {
    	if(nw>k) return 0;RI o=id[nw];vector<int>::iterator it;
    	for(it=P[o][x].begin();it!=P[o][x].end();++it) if(!vis[*it]&&(++nw,!Check(*it))) return 0;//把中间的障碍全部清除
    	return vis[x]=1;//标记被杀死
    }
    int op;I bool cmp(CI x,CI y) {return (p[x]<p[y])==op;}
    int main()
    {
    	RI i,j,u;for(scanf("%d%d",&k,&n),i=1;i<=k;++i) scanf("%d%d",&s[i].x,&s[i].y);
    	for(i=1;i<=n;++i) scanf("%d%d",&p[i].x,&p[i].y);
    	for(i=1;i<=k;++i) for(j=1;j<=n;op=s[i]<p[j],sort(P[i][j].begin(),P[i][j].end(),cmp),++j)//枚举人i和怪物j,求出之间的怪物
    		for(u=1;u<=n;++u) j^u&&(s[i]-p[j]).S()==(s[i]-p[u]).S()&&(s[i]<p[u])==(p[u]<p[j])&&(P[i][j].push_back(u),0);//枚举怪物判断是否在它们中间
    	RI fg,t=0;for(i=1;i<=n;t+=fg,++i) {for(j=1;j<=k;++j) id[j]=j;
    		do {memset(vis,0,sizeof(vis)),nw=1,fg=Check(i);} W(!fg&&next_permutation(id+1,id+k+1));}//暴力全排列
    	return printf("%d
    ",t),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    MySQL SQL语句总结
    JavaFx通用查询、跳转创建、修改页面、关闭舞台工具类
    反射工具类
    SpringBoot将数据写入word模板,生成word文档
    vscode设置中文的方法
    Flex 布局
    处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler” •使用了托管的处理程序,但是未安装或未完整安装 ASP.NET。
    第一周助教总结
    JS时间转换
    ES 安装常见错误
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF698D.html
Copyright © 2011-2022 走看看