T1 乘积分解
题解:
预处理出\(n\)的约数,用\(F[i][j]\)记录从排序后的第i个因数出发,连续\(j\)个因数的乘积。 要求\(fFi][j]<=n\),且\(j<=k\)
\(code\):
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<ctype.h>
#include<ctime>
#define ll long long
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
while(!isdigit(tt=gc()));x=tt-'0';
while(isdigit(tt=gc())) x=x*10+tt-'0';
}
ll t,n,m,tot;
ll s[100005],fac[100005][30];
double start;
bool dfs(ll x,ll rest,ll fact)
{
if(!rest) return fact==n;rest--;
while(x)
{
if(x+rest>tot) return 0;
if(fac[x][rest]>n||fac[x][rest]*fact>n) return 0;
if(dfs(x+1,rest,fact*s[x])) return 1;x++;
}
}
int main()
{
read(t);
while(t--)
{
bool flag=0;
ll fact=1;
read(n),read(m);
if(n==1&&m==2){puts("NIE");continue;}
if(m<=2)
{
puts("TAK");
continue;
}
for(int i=1;i<=m;i++,fact*=i)
if(fact>n)
{
flag=1;
break;
}
if(flag) {puts("NIE");continue;}
int i;tot=0;
for (i=1;i*i<n;i++)
if(n%i==0) s[++tot]=i,s[++tot]=n/i;
if(i*i==n)s[++tot]=i;
sort(s+1,s+tot+1);fact=1;
for(int i=1;i<=tot;i++,fact=1)
for(int j=0;j<m&&i+j<=tot;j++)
{
if(fact<=n) fact*=s[i+j];
fac[i][j]=fact;
}
// for(int i=1;i<=10;i++)
// printf("%d ",f[3][i]);
if(dfs(1,m,1)) printf("TAK\n");
else printf("NIE\n");
}
}
//1 1000000000 6
T2 扫雷游戏
题解:
预处理\(i\),\(j\)两点穿过的直线,爆搜即可
\(code:\)
#include<stdio.h>
#include<cstring>
#include<algorithm>
#define lowbit(x) x&-x
using namespace std;
struct node{
int x,y;
inline node(int a=0,int b=0)
{x=a,y=b;}
}a[20];
int n,k;
int f[1<<17],line[20][20];
int dfs(int s)
{
if(~f[s]) return f[s];
int cnt=0,t=s;
while(t) cnt++,t^=lowbit(t);
if(n-k>=cnt) return f[s]=0;
if(cnt==1) return f[s]=1;
f[s]=1e9+9;
for(int i=0;i<n;i++) if(s>>i&1)
for(int j=i+1;j<n;j++) if(s>>j&1)
f[s]=min(f[s],dfs(s&(~line[i][j]))+1);
return f[s];
}
int main()
{
for(int t=1;t<=2;t++)
{
memset(f,-1,sizeof(f));
memset(line,0,sizeof(line));
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[i]=node(x,y);
}
//(ay-ky)(ax-bx)==(ax-kx)(ay-by)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) if(i!=j)
for(int k=0;k<n;k++)
if((a[i].y-a[k].y)*(a[i].x-a[j].x)==(a[i].x-a[k].x)*(a[i].y-a[j].y))
line[i][j]|=(1<<k);
printf("%d\n",dfs((1<<n)-1));
}
}
T3 数字消除游戏
题解:
A*+迭代加深+扩展周围有的颜色+不真实赋值,标记联通性
\(code:\)
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stdlib.h>
#include<ctype.h>
#define eps 1e-7
#define ll long long
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
while(!isdigit(tt=gc()));x=tt-'0';
while(isdigit(tt=gc())) x=x*10+tt-'0';
}
int n;
int a[10][10],book[10][10];
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
bool cl[10];
int gujia()
{
int col=0;
for(int i=0;i<=5;i++) cl[i]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(!cl[a[i][j]]&&book[i][j]!=1)
{
cl[a[i][j]]=1;
col++;
}
return col;
}
void dfs(int x,int y,int c)
{
book[x][y]=1;
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx<=0||ty<=0||tx>n||ty>n) continue;
if(book[tx][ty]==1) continue;
book[tx][ty]=2;
if(a[tx][ty]==c) dfs(tx,ty,c);
}
}
int fill(int c)
{
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]==c&&book[i][j]==2)
{
sum++;
dfs(i,j,c);
}
return sum;
}
bool astar(int dep,int maxdep)
{
int g=gujia();
if(dep+g>maxdep) return 0;
if(!g) return 1;
int temp[10][10];
for(int i=0;i<=5;i++)
{
for(int c=1;c<=n;c++)
for(int j=1;j<=n;j++)
temp[c][j]=book[c][j];
if(fill(i)&&astar(dep+1,maxdep)) return 1;
for(int c=1;c<=n;c++)
for(int j=1;j<=n;j++)
book[c][j]=temp[c][j];
}
return 0;
}
int main()
{
while(1)
{
read(n);
if(!n) return 0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
read(a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
book[i][j]=0;
dfs(1,1,a[1][1]);
for(int dep=0;;dep++)
if(astar(0,dep))
{
printf("%d\n",dep);
break;
}
}
}
原文地址:https://www.cnblogs.com/KatouKatou/p/9788925.html
时间: 2024-09-29 04:05:39