BZOJ 2335


2335: [SCOI2011]飛鏢

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 457  Solved: 140
[Submit][Status][Discuss]

Description

飛鏢是在歐洲頗爲流行的一項運動。它的鏢盤上分爲20個扇形區域,分別標有120的分值,每個區域中有單倍、雙倍和三倍的區域,打中對應的區域會得到分值乘以倍數所對應的分數。例如打中18分裏面的三倍區域,就會得到54分。另外,在鏢盤的中央,還有小紅心大紅心,分別是25分和50分。

通常的飛鏢規則還有一條,那就是在最後一鏢的時候,必須以雙倍結束戰鬥,纔算獲勝。也就是說,當還剩12分的時候,必須打中雙倍的6纔算贏,而打中單倍的12或者三倍的4則不算。特別的,大紅心也算雙倍(雙倍的25)。在這樣的規則下,3鏢能解決的最多分數是170(兩個三倍的20,最後用大紅心結束)

現在,lxhgww把原來的120分的分值變爲了1K分,同時把小紅心的分數變爲了M(大紅心是其雙倍),現在lxhgww想知道能否在3鏢內(可以不一定用滿3鏢)解決X分。同樣的,最後一鏢必須是雙倍(包括大紅心)。

Input

Output

一行,包括一個數字,表示這T組數據中,能夠被解決的數據數目。

Sample Input

5
1 2 2 10 20
1 3 2 15 25
2 2 5 200 170

Sample Output

4

HINT

1<=T<=1000000,20<=K1,M1,X1,D1,D2,D3<=10^9




這題實際上就是問一個不定方程:ax+by+2z=A(1<=x,y,z<=K或x,y,z中的一些爲m)
yfzcsc的SB做法 依次check 2x=A,x+2y=A,2x+2y=A,3x+2y=A,x+y+2z=A,x+2y+2z=A,x+3y+2z=A,2x+2y+2z=A,2x+3y+2z=A,3x+3y+2z=A是否有解...

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
bool check(long long K,long long M,long long X){
	if(!((X%2==0&&((X>=2&&X<=2*K)||X==2*M))))return false;
	return true;
}
bool check12(long long K,long long M,long long X){
	if(check(K,M,X-M))return true;
	if((X<3||X>3*K)&&(X-2*M<1||X-2*M>K))return false;
	return true;
}
bool check22(long long K,long long M,long long X){
	if(X%2!=0)return false;
	if(check(K,M,X-M*2))return true;
	if((X<4||X>4*K)&&(X-2*M<2||X-2*M>K*2||(X-2*M)%2!=0))return false;
	return true;
}

bool check4(long long A,long long K){
	if(A<5||A>K*5)return true;
	if(A==6||A==5*K-1)return true;
	return false;
}
bool check32(long long K,long long M,long long X){
	
	if(check4(X,K)&&(X-2*M<3||X-2*M>K*3||(X-2*M)%3!=0))return false;
	return true;
}
bool check112(long long K,long long M,long long X){
	if(check12(K,M,X-M))return true;
	if(X>K*4&&(X-2*M<2||X-2*M>K*2))return false;
	return true;
}
bool check122(long long K,long long M,long long X){
	if(check12(K,M,X-M*2))return true;
	if(check22(K,M,X-M))return true;
	if(X>K*5&&(X-2*M<3||X-2*M>K*3))return false;
	return true;
}
bool check132(long long K,long long M,long long X){
	if(check32(K,M,X-M))return true;
	if(X>K*6&&(X-2*M<4||X-2*M>K*4))return false;
	return true;
}
bool check222(long long K,long long M,long long X){
	if(check22(K,M,X-M*2))return true;
	if(X%2==1)return false;
	else X/=2;
	if(X>3*K&&(X-M<2||X-M>2*K))return false;
	return true;
}
bool check232(long long K,long long M,long long X){
	if(check32(K,M,X-M*2))return true;
	if((X==7*K-1||X>K*7)&&check4(X-2*M,K))return false;
	return true;
}
bool check332(long long K,long long M,long long X){
	if((X==8*K-1||X>K*8)&&(X-M*2<6||X-M*2>6*K||(X-M*2)%3!=0))return false;
	return true;
}
int main(){
	long long t,a1,b1,c1,d1,x;
	long long a2,b2,c2,d2,k;
	long long a3,b3,c3,d3,m,ans=0;
	scanf("%lld",&t);
	scanf("%lld%lld%lld%lld%lld",&a1,&b1,&c1,&d1,&k);
	scanf("%lld%lld%lld%lld%lld",&a2,&b2,&c2,&d2,&m);
	scanf("%lld%lld%lld%lld%lld",&a3,&b3,&c3,&d3,&x);
	for(int i=1;i<=t;++i){
		if(check(k,m,x))ans++;
		else if(check12(k,m,x))ans++;
		else if(check22(k,m,x))ans++;
		else if(check32(k,m,x))ans++;
		else if(check112(k,m,x))ans++;
		else if(check122(k,m,x))ans++;
		else if(check132(k,m,x))ans++;
		else if(check222(k,m,x))ans++;
		else if(check232(k,m,x))ans++;
		else if(check332(k,m,x))ans++;
		k=(1ll*a1*k%d1*k%d1+1ll*b1*k%d1+c1)%d1+20;
		m=(1ll*a2*m%d2*m%d2+1ll*b2*m%d2+c2)%d2+20;
		x=(1ll*a3*x%d3*x%d3+1ll*b3*x%d3+c3)%d3+20;
	}
	printf("%lld\n",ans);
}


另附wxh的大佬做法(當然我的做法又好想又好寫又好調,A的比他快)

#include<bits/stdc++.h>

using namespace std;

long long t,a1,a2,a3,b1,b2,b3,c1,c2,c3,d1,d2,d3,k,m,x,ans;

inline bool f0(long long x) { return (x>=0)&&(x%m==0)&&(x/m!=1)&&(x<=m*6); }

inline bool f1(long long x) { return (x>=0)&&(x<=k*2)&&((x&1)==0); }

inline bool f2(long long x) { return (x>=0)&&(x<=k*5)&&(x!=k*5-1); }

inline bool f3(long long x) { return (x>=0)&&(x<=k*8)&&(x!=k*8-1); }

inline bool f4(long long x) { return (x>=0)&&((x<=k)||f1(x)||(x<=k*3&&x%3==0)); }

inline bool f5(long long x) { return (x>=0)&&(f2(x)||(x<=k*4)||(x<=k*6&&x%3==0)); }

int main()
{
    scanf("%lld",&t);
    scanf("%lld%lld%lld%lld%lld",&a1,&b1,&c1,&d1,&k);
    scanf("%lld%lld%lld%lld%lld",&a2,&b2,&c2,&d2,&m);    
    scanf("%lld%lld%lld%lld%lld",&a3,&b3,&c3,&d3,&x);
    for(int T1=1;T1<=t;T1++)
    {
        if(f0(x)||f1(x)||f2(x)||f2(x-m)||f3(x)||f4(x-m*2)||f4(x-m*3)||f4(x-m*4)||f5(x-m*2))
            ans++;
        k=(k*k%d1*a1%d1+b1*k%d1+c1)%d1+20;
        m=(m*m%d2*a2%d2+b2*m%d2+c2)%d2+20;
        x=(x*x%d3*a3%d3+b3*x%d3+c3)%d3+20;
    }
    if(ans==97394) ans=97382;
    return printf("%lld\n",ans),0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章