站外题求调
  • 板块题目总版
  • 楼主THUHS_Finder
  • 当前回复6
  • 已保存回复6
  • 发布时间2021/8/2 20:54
  • 上次更新2023/11/4 12:12:05
查看原帖
站外题求调
231641
THUHS_Finder楼主2021/8/2 20:54

题面:

二维平面上有N个点,有一把刷子,刷一次可以把一条直线上的所有点都刷掉。问最少刷多少次,可以把全部的点都刷完。

hack 数据:

6
1 1
1 1
41 -9
83 -73
-1 69
-29 -81

无输出,应该是死循环了,求调。

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int x[20], y[20];
int dp[1<<16], line[20][20];
int same[20],same2[20];
int n;
inline int check(int i,int j,int k)
{
    int y2=y[j];
	int y1=y[i];
	int y3=y[k];
    int x2=x[j];
	int x1=x[i];
	int x3=x[k];
    if(y3*(x2-x1)==(y2-y1)*x3+x2*y1-x1*y2) return 1;
    else return 0;
}
void pre(int n)
{
	for(int i=0;i<n;i++)
    {
        line[i][i]=(1<<i);
        for(int j=i+1;j<n;j++)
        {
        	if(x[i]==x[j] and y[i]==y[j]) continue;
            for(int k=0;k<n;k++)
            {
                if(check(i,j,k)) line[i][j]|=(1<<k);
            }
        }
	}
}
int dfs(int status)
{
	if(status == (1 << n) - 1)
	{
		return 0;
	}
	if(dp[status]!=0x3f3f3f3f) return dp[status];
	
  
	for(int i= 0;i<n; i++)
	{
		if(!(status&(1<<i)))
		{
			
			for (int j =i+1;j<n; j++)
			{
				int mask = status|line[i][j];
				//cout<<mask<<endl;
				dp[status] = min(dp[status], dfs(mask) + 1);
			//	cout<<dp[status]<<endl;
			}
		}
		//cout<<dp[status]<<endl;
		
	}
	return dp[status];
}
int main()
{
	int T;
	scanf("%d",&T);
    while(T--)
    {
        cin>>n; 	
        memset(line,0,sizeof(line));
        memset(dp,0x3f3f3f3f,sizeof(dp));
        dp[(1<<n)-1]=0;
        for(int i=0;i<n;i++)
		{
			scanf("%d%d",&x[i],&y[i]);
		}
		if(n==1)
		{
			cout<<1<<endl;
			
		}
		else
		{
			pre(n);
 
	//	cout<<(1<<3)<<endl;
	//	1000
		cout<<dfs(0)<<endl;
		}
		
    }
    return 0;
}
2021/8/2 20:54
加载中...