NOIP模拟赛
Problem |
A-B |
还是N皇后 |
比萨 |
细菌 |
Program (File Type: pas/c/cpp) |
dec |
queens |
pizza |
disease |
Input File |
dec.in |
queens.in |
|
|
Output File |
dec.out |
queens.out |
|
|
Time Limit |
1s |
4s |
|
|
Memory Limit |
128M |
128M |
128M |
128M |
Problems
Problem #1: A-B(dec)
Description
出题是一件痛苦的事情!
题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的A+B Problem,改用A-B了哈哈!
好吧,题目是这样的:给出一串数以及一个数字C,要求计算出所有A-B=C的数对的个数。(不同位置的数字一样的数对算不同的数对)
Input Format
第一行包括2个非负整数N和C,中间用空格隔开。
第二行有N个整数,中间用空格隔开,作为要求处理的那串数。
Output Format
输出一行,表示该串数中包含的所有满足A-B=C的数对的个数。
Sample Input
4 1
1 1 2 3
Sample Output
3
Data Limit
对于90%的数据,N <= 2000;
对于100%的数据,N <= 200000。
所有输入数据都在longint范围内。
#include
#include
#include
#include
using namespace std;
int n,c,k[200001],num[200001],ge[200001],p,pp,kk=0,head=0,tail=0;
long long ans=0;
int main()
{
freopen("dec.in","r",stdin);
freopen("dec.out","w",stdout);
memset(ge,0,sizeof(ge));
scanf("%d%d",&n,&c);
for(int i=0;i
sort(k+0,k+n);
num[0]=k[0];
ge[0]=1;
p=k[0];
for(int i=1;i
if(p==k[i])
++ge[kk];
else
{
++kk;
++ge[kk];
num[kk]=k[i];
p=k[i];
}
}
while(head
while(num[head]-num[tail]>c)
++tail;
while(num[head]-num[tail]
if(num[head]-num[tail]==c)
{
ans+=(ge[head]*ge[tail]);
++tail;++head;
}
}
printf("%d\n",ans);
return 0;
}
Problem #2: 还是N皇后(queens)
Description
正如题目所说,这题是著名的N皇后问题。
Input Format
第一行有一个N。接下来有N行N列描述一个棋盘,“*”表示可放“.”表示不可放。
Output Format
输出方案总数。
Sample Input
4
**.*
****
****
****
Sample Output
1
Data Limit
对于30%的数据,N≤10;
对于100%的数据,N≤14;
#include
#include
#include
using namespace std;
int upperlim;
unsigned long long int sum;
char ch;
int upp[16];
void NQueen(int row,int row2,int ld,int rd)
{
int pos,p;
if (row!=upperlim)//如果没全放进去
{
pos=upp[row2] & ~ (row | ld | rd);
while(pos!=0)
{
p=pos & -pos;
pos=pos-p;
NQueen(row+p,row2+1,(ld+p)<<1,(rd+p)>>1);
}
}
else
{
++sum;
//cout<
}
int main()
{
freopen("queens.in","r",stdin);
freopen("queens.out","w",stdout);
memset(upp,0,sizeof(upp));
int n;
scanf("%d",&n);
for(int i=0;i
cin>>ch;
upp[i]<<=1;
if(ch=='*')
upp[i]|=1;
}
upperlim=(1<
NQueen(0,0,0,0);
printf("%d\n",sum);
return 0;
}
比萨(nhoi2009pj3)
Time Limit:1000MS Memory Limit:65536K
Total Submit:3 Accepted:3
Description
NH的最大比萨店为即将来临的节日准备了 T 种不同加味的原料,但考虑到NH人的口味和其它一些因素,原料的使用有 N 种限制。
T种不同原料的编号为1..T。一个限制如“5 3”即表示5号和3号加味原料不能同时使用。如此,此时使用三种原料3,5,6的比萨是不允许的。
现在请你帮忙计算在上面条件下,最多可以制作多少不同的比萨(包括不添加任何加味原料的)。
Input
第一行:两个整数:T 和 N。
下面有N行:每行表示一种限制。每行的第一个整数 Z(1≦Z≦ T)表示这行后面有Z个表示原料编号的整数,这些原料不能同时出现在一个比萨中。
Output
只一行,一个整数表示在上面的限制下最多可以制成多少种不同比萨。
Sample Input
6 5
1 1
2 4 2
3 3 2 6
1 5
3 3 4 6
Sample Output
10
答案说明:
无加料;2;
2和3;2和6;
3;3和4;
3和6;4;
4和6;6。
Hint
1≦T≦20
1≦N≦52
#include
#include
#include
using namespace std;
int t,n,k,ki,ans=0;
bool check[1500000];
int tmp[53];
int main()
{
freopen("pizza.in","r",stdin);
freopen("pizza.out","w",stdout);
scanf("%d%d",&t,&n);
memset(tmp,0,sizeof(tmp));
memset(check,true,sizeof(check));
for(int i=0;i
{
scanf("%d",&k);
for(int j=0;j
{
scanf("%d",&ki);
tmp[i]+=(1<<(ki-1));
}
}
//cout<<"!"<
for(int i=0;i
{
//cout<<"!"<
for(int j=0;j<=(1<
{
int tt=(j&tmp[i]);
if(tt==tmp[i])
{
check[j]=false;
//cout<
//cout<
}
}
}
//cout<<(~1)<
for(int i=0;i<=(1<
if(check[i])
{
++ans;
//cout<<"ans"<
}
printf("%d",ans);
}
细菌(2009jxd)
Time Limit:1000MS Memory Limit:65536K
Total Submit:3 Accepted:1
Description
近期,农场出现了D (1<= D <=15)种细菌。John 要从他的 N (1<= N <=1,000)头奶牛中尽可能多地选些产奶。但是如果选中的奶牛携带了超过 K (1<= K <=D)种不同细菌,所生产的奶就不合格。请你帮助John 计算出最多可以选择多少头奶牛。
Input
第一行:三个整数 N, D, K
下面N行:第i行表示一头牛所携带的细菌情况。第一个整数 di 表示这头牛所携带的细菌种类数,后面di个整数表示这些细菌的各自种类标号。
Output
只一个数 M,最大可选奶牛数。
Sample Input
6 3 2
0
1 1
1 2
1 3
2 2 1
2 2 1
Sample Output
5
选择:
1,2,3,5,6
只有1#和2#两种细菌
#include
#include
#include
using namespace std;
int n,d,k,ans=0;
int bin[1001][17];
int cow[1001];
bool check[17];
void Resident_Evil(int z,int ge)
{
if(z>d)
{
if(ge>k)
return;
int tmp=0;
for(int i=1;i<=n;i++)
{
bool bo=true;
for(int j=1;j<=cow[i];j++)
if(!check[bin[i][j]])
{
bo=false;
break;
}
if(bo)
tmp++;
}
ans=max(ans,tmp);
//cout<
return;
}
check[z]=true;
Resident_Evil(z+1,ge+1);
check[z]=false;
Resident_Evil(z+1,ge);
}
int main()
{
freopen("disease.in","r",stdin);
freopen("disease.out","w",stdout);
memset(check,false,sizeof(check));
scanf("%d%d%d",&n,&d,&k);
for(int i=1;i<=n;++i)
{
scanf("%d",&cow[i]);
for(int j=1;j<=cow[i];++j)
scanf("%d",&bin[i][j]);
}
Resident_Evil(1,0);
printf("%d",ans);
return 0;
}
#include
#include
#include
using namespace std;
int n,d,k,ans=0,ni,tmp;
bool bo[100000];
int cow[1001];
int check(int i)
{
int t=0;
while(i>0)
{
int p=i&-i;
t++;
i-=p;
}
return t;
}
int main()
{
freopen("disease.in","r",stdin);
freopen("disease.out","w",stdout);
memset(bo,true,sizeof(bo));
memset(cow,0,sizeof(cow));
scanf("%d%d%d",&n,&d,&k);
for(int i=1;i<=n;++i)
{
scanf("%d",&ni);
for(int j=0;j
scanf("%d",&tmp);
cow[i]+=(1<<(tmp-1));
}
}
for(int i=1;i<=(1<
if(check(i)>k)
bo[i]=false;
}
for(int i=1;i<=(1<
int jl=0;
if(bo[i])
for(int j=1;j<=n;++j)
{
int tt=(cow[j]&i);
if(tt==cow[j])
++jl;
}
if(jl>ans)
ans=jl;
}
/* for(int i=1;i<=(1<
cout<
printf("%d",ans);
return 0;
}