zoukankan      html  css  js  c++  java
  • Codeforces 698D Limak and Shooting Points (搜索)

    题目链接

    https://codeforces.com/contest/698/problem/D

    题解

    玄妙好题啊
    对于每个元素(j)判断(j)是否可被射中。假设我们要用第(i)个弓箭射中第(j)个目标,那么在射中之前有若干个目标是我们需要先射中的。但我们并不知道应该用哪些目标射中。
    于是我们可以枚举一个(1)(m)的全排列(P_k), 然后进行BFS. 初始队列中只有(j),每次取出队首元素(设队首在队列中的位置为(k)),然后用(P_k)去射队首元素,然后加入队列。若队列中元素个数超过(m), 则无解(以这个顺序射中(j)是不可能的)。
    时间复杂度(O(k!kn))

    代码

    #include<bits/stdc++.h>
    #define llong long long
    #define mkpr make_pair
    #define riterator reverse_iterator
    using namespace std;
    
    inline int read()
    {
    	int x = 0,f = 1; char ch = getchar();
    	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    	return x*f;
    }
    
    const int N = 1000;
    const int M = 7;
    struct Point
    {
    	int x,y;
    } a[M+2],b[N+3];
    vector<int> l[M+2][N+3];
    int permu[M+2];
    int que[N+3]; bool vis[N+3];
    int n,m;
    
    int main()
    {
    	scanf("%d%d",&m,&n);
    	for(int i=1; i<=m; i++) scanf("%d%d",&a[i].x,&a[i].y);
    	for(int i=1; i<=n; i++) scanf("%d%d",&b[i].x,&b[i].y);
    	for(int i=1; i<=m; i++)
    	{
    		for(int j=1; j<=n; j++)
    		{
    			for(int k=1; k<=n; k++) if(k!=j)
    			{
    				if(1ll*(b[j].x-a[i].x)*(b[k].y-a[i].y)==1ll*(b[j].y-a[i].y)*(b[k].x-a[i].x) && (1ll*(a[i].x-b[k].x)*(b[j].x-b[k].x)<0 || (a[i].x==b[k].x&&1ll*(a[i].y-b[k].y)*(b[j].y-b[k].y)<0)))
    				{
    					l[i][j].push_back(k);
    				}
    			}
    		}
    	}
    	int fans = 0;
    	for(int j=1; j<=n; j++)
    	{
    		for(int i=1; i<=m; i++) permu[i] = i;
    		bool ans = false;
    		do
    		{
    			for(int i=1; i<=n; i++) vis[i] = false;
    			bool cur = true;
    			int hd = 1,tl = 1; que[tl] = j; vis[j] = true;
    			while(hd<=tl)
    			{
    				int u = que[hd];
    				for(int i=0; i<l[permu[hd]][u].size(); i++)
    				{
    					if(vis[l[permu[hd]][u][i]]) continue;
    					que[++tl] = l[permu[hd]][u][i]; vis[l[permu[hd]][u][i]] = true;
    					if(tl>m) {cur = false; break;}
    				}
    				if(!cur) {break;}
    				hd++;
    			}
    			if(cur) {ans = true; break;}
    		} while(next_permutation(permu+1,permu+m+1));
    		if(ans) {fans++;}
    	}
    	printf("%d
    ",fans);
    	return 0;
    }
    
  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/suncongbo/p/12348088.html
Copyright © 2011-2022 走看看