标签:题目 style main 计算 names using 位置 tab 计数
时间限制:1s
内存限制:256MB
【问题描述】
对于一个1~n的排列,如果满足第i个数|ai-i|<=k,则称该排列为K-近似排列。
现在排列的若干位置已经确定,你需要计算剩下的数有多少种排列方法使得形成的排列是K-近似排列。
【输入】
输入文件名为count.in。
第一行一个数T(<=10),表示数据组数
对于每一组数据:
第一行三个数n,m,k,分别表示排列长度、已确定位置的个数和近似参数K
接下来m行,每行两个数x、y,表示已经确定第x个数是y
【输出】
输出文件名为count.out。
对于每组数据输出一行,包含一个数,表示方法个数(对1,000,000,007取模)
【输入输出样例】
count.in |
count.out |
1 4 1 1 2 3 |
1 |
【数据说明】
对于30%的数据,1<=n,m<=10,k<=2
对于50%的数据,1<=n,m<=20,k<=2
对于70%的数据,1<=n<=100000,m<=100,k<=2
对于100%的数据,1<=n<=10^9,m<=100,k<=2
坑啊,题目给的样例不对,他写的是2,其实是1.!
小暴力50分
#include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<cstring> #include<cmath> using namespace std; int n,m,k,t; int a[100009]; bool vis[100009]; long long ans; void dfs(int x) { if(x==n+1) { ans++; return ; } if(a[x]) dfs(x+1); else { if(x>=3) if(!vis[x-k]) { vis[x-k]=1; dfs(x+1); vis[x-k]=0; return ; } for(int i=max(x-k,1);i<=min(x+k,n);i++) if(!vis[i]) { vis[i]=1; dfs(x+1); vis[i]=0; } } return ; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) a[i]=0,vis[i]=0; ans=0; for(int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); a[x]=y;vis[y]=1; } dfs(1); printf("%lld\n",ans); } return 0; }
标签:题目 style main 计算 names using 位置 tab 计数
原文地址:http://www.cnblogs.com/CLGYPYJ/p/7625296.html