1003 贪心
对于111...10....000 这样的序列,
a 为1的个数,b为0的个数,易得当
x= a / (a + b) 时 f最小。
讲串分成若干段 1..10..0 , 1..10..0 ,
要满足x非递减 。
对于 xi > xi+1 这样的合并 即可。
const int maxn = 100008 ;
struct Node{
int one ;
int zero ;
double f ;
Node(){}
Node(int o , int z) : one(o) , zero(z){}
};
int n ;
int a[maxn] ;
stack<Node> stk ;
vector<Node> lis ;
double answer(){
int i , l , r ;
l = 1 ;
while(a[l] == 0 && l <= n) l++ ;
r = n ;
while(a[r] == 1 && r >= 1) r-- ;
if(l > r) return 0.0 ;
lis.clear() ;
Node nd(0 , 0) ;
int c = 1 ;
for(i = l ; i <= r ; i++){
if(c && a[i] == 1) nd.one++ ;
else if(c && a[i] == 0){
nd.zero++ ;
c = 0 ;
}
else if(!c && a[i] == 0) nd.zero++ ;
else if(!c && a[i] == 1){
nd.f = double(nd.one) / double(nd.one + nd.zero) ;
lis.push_back(nd) ;
nd = Node(1 , 0) ;
c = 1 ;
}
}
nd.f = double(nd.one) / double(nd.one + nd.zero) ;
lis.push_back(nd) ;
/*
for(i = 0 ; i < lis.size() ; i++){
nd = lis[i] ;
cout<< nd.one <<" " <<nd.zero<<endl ;
}
*/
while(! stk.empty()) stk.pop() ;
for(i = 0 ; i < lis.size() ; i++){
nd = lis[i] ;
while(! stk.empty() && nd.f < stk.top().f){
nd.one += stk.top().one ;
nd.zero += stk.top().zero ;
nd.f = double(nd.one) / double(nd.one + nd.zero) ;
stk.pop() ;
}
stk.push(nd) ;
}
double sum = 0.0 ;
while(! stk.empty()){
nd = stk.top() ; stk.pop() ;
sum += (1.0 - nd.f)*(1.0 - nd.f) * nd.one + nd.f * nd.f * nd.zero ;
}
return sum ;
}
int main(){
int t , i ;
cin>>t ;
while(t--){
cin>>n ;
for(i = 1 ; i <= n ; i++) scanf("%d" , &a[i]) ;
printf("%.6lf\n" , answer()) ;
}
return 0 ;
}
1005 奇偶染色, 2种染法,取最大值
const int maxn = 108 ;
typedef unsigned long long ULL ;
int a[maxn][maxn] ;
int n , m ;
int d[4][2] = {{-1 ,0} , {0 ,-1} , {0 , 1} , {1 , 0}} ;
int can(int x , int y){
return 1 <= x && x <= n && 1 <= y && y <= m ;
}
ULL sum(){
ULL t = 0ULL ;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= m ; j++){
if(a[i][j] == 0) continue ;
int c = 0 ;
for(int k = 0 ; k < 4 ; k++){
int x = i + d[k][0] ;
int y = j + d[k][1] ;
if(can(x , y) && a[x][y] == 0) c++ ;
}
t += (ULL) pow(2.0 , double(c)) ;
}
}
return t ;
}
int main(){
int t , i , j ;
cin>>t ;
while(t--){
cin>>n>>m ;
memset(a , 0 , sizeof(a)) ;
for(i = 1 ; i <= n ; i++){
for(j = 1 ; j <= m ; j++) if((i+j)&1) a[i][j] = 1 ;
}
ULL ans = sum() ;
memset(a , 0 , sizeof(a)) ;
for(i = 1 ; i <= n ; i++){
for(j = 1 ; j <= m ; j++) if(((i+j)&1) == 0) a[i][j] = 1 ;
}
ans = max(ans , sum()) ;
cout<< ans << endl ;
}
return 0;
}
1007
多推导几步,找公式,需要用到大数 ,MyEclipse过期了。
#define MAXN 9999
#define MAXSIZE 10
#define DLEN 4
class BigNum
{
private:
int a[1000]; //可以控制大数的位数
int len; //大数长度
public:
BigNum(){ len = 1;memset(a,0,sizeof(a)); } //构造函数
BigNum(const int); //将一个int类型的变量转化为大数
BigNum(const char*); //将一个字符串类型的变量转化为大数
BigNum(const BigNum &); //拷贝构造函数
BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
friend istream& operator>>(istream&, BigNum&); //重载输入运算符
friend ostream& operator<<(ostream&, BigNum&); //重载输出运算符
BigNum operator+(const BigNum &) const; //重载加法运算符,两个大数之间的相加运算
BigNum operator-(const BigNum &) const; //重载减法运算符,两个大数之间的相减运算
BigNum operator*(const BigNum &) const; //重载乘法运算符,两个大数之间的相乘运算
BigNum operator/(const int &) const; //重载除法运算符,大数对一个整数进行相除运算
BigNum operator^(const int &) const; //大数的n次方运算
int operator%(const int &) const; //大数对一个int类型的变量进行取模运算
bool operator>(const BigNum & T)const; //大数和另一个大数的大小比较
bool operator>(const int & t)const; //大数和一个int类型的变量的大小比较
void clean()
{
while(len > 1 && !a[len-1]) len--;
}
void print(); //输出大数
};
BigNum::BigNum(const int b) //将一个int类型的变量转化为大数
{
int c,d = b;
len = 0;
memset(a,0,sizeof(a));
while(d > MAXN)
{
c = d - (d / (MAXN + 1)) * (MAXN + 1);
d = d / (MAXN + 1);
a[len++] = c;
}
a[len++] = d;
}
BigNum::BigNum(const char*s) //将一个字符串类型的变量转化为大数
{
int t,k,index,l,i;
memset(a,0,sizeof(a));
l=strlen(s);
len=l/DLEN;
if(l%DLEN)
len++;
index=0;
for(i=l-1;i>=0;i-=DLEN)
{
t=0;
k=i-DLEN+1;
if(k<0)
k=0;
for(int j=k;j<=i;j++)
t=t*10+s[j]-'0';
a[index++]=t;
}
}
BigNum::BigNum(const BigNum & T) : len(T.len) //拷贝构造函数
{
int i;
memset(a,0,sizeof(a));
for(i = 0 ; i < len ; i++)
a[i] = T.a[i];
}
BigNum & BigNum::operator=(const BigNum & n) //重载赋值运算符,大数之间进行赋值运算
{
int i;
len = n.len;
memset(a,0,sizeof(a));
for(i = 0 ; i < len ; i++)
a[i] = n.a[i];
return *this;
}
istream& operator>>(istream & in, BigNum & b) //重载输入运算符
{
char ch[MAXSIZE*4];
int i = -1;
in>>ch;
int l=strlen(ch);
int count=0,sum=0;
for(i=l-1;i>=0;)
{
sum = 0;
int t=1;
for(int j=0;j<4&&i>=0;j++,i--,t*=10)
{
sum+=(ch[i]-'0')*t;
}
b.a[count]=sum;
count++;
}
b.len =count++;
return in;
}
ostream& operator<<(ostream& out, BigNum& b) //重载输出运算符
{
int i;
cout << b.a[b.len - 1];
for(i = b.len - 2 ; i >= 0 ; i--)
{
cout.width(DLEN);
cout.fill('0');
cout << b.a[i];
}
return out;
}
BigNum BigNum::operator+(const BigNum & T) const //两个大数之间的相加运算
{
BigNum t(*this);
int i,big; //位数
big = T.len > len ? T.len : len;
for(i = 0 ; i < big ; i++)
{
t.a[i] +=T.a[i];
if(t.a[i] > MAXN)
{
t.a[i + 1]++;
t.a[i] -=MAXN+1;
}
}
if(t.a[big] != 0)
t.len = big + 1;
else
t.len = big;
return t;
}
BigNum BigNum::operator-(const BigNum & T) const //两个大数之间的相减运算
{
int i,j,big;
bool flag;
BigNum t1,t2;
if(*this>T)
{
t1=*this;
t2=T;
flag=0;
}
else
{
t1=T;
t2=*this;
flag=1;
}
big=t1.len;
for(i = 0 ; i < big ; i++)
{
if(t1.a[i] < t2.a[i])
{
j = i + 1;
while(t1.a[j] == 0)
j++;
t1.a[j--]--;
while(j > i)
t1.a[j--] += MAXN;
t1.a[i] += MAXN + 1 - t2.a[i];
//for(int k=0;k<big;k++)
// printf("%d %d\n",t1.a[k],t2.a[k]);
}
else
t1.a[i] -= t2.a[i];
}
t1.len = big;
//for(i=0;i<big;i++) cout<<t1.a[i]<<endl;
while(t1.a[big - 1] == 0 && t1.len > 1)
{
t1.len--;
big--;
}
return t1;
}
BigNum BigNum::operator*(const BigNum & T) const //两个大数之间的相乘运算
{
BigNum ret;
int i,j,up;
int temp,temp1;
for(i = 0 ; i < len ; i++)
{
up = 0;
for(j = 0 ; j < T.len ; j++)
{
temp = a[i] * T.a[j] + ret.a[i + j] + up;
if(temp > MAXN)
{
temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
up = temp / (MAXN + 1);
ret.a[i + j] = temp1;
}
else
{
up = 0;
ret.a[i + j] = temp;
}
}
if(up != 0)
ret.a[i + j] = up;
}
ret.len = i + j;
while(ret.a[ret.len - 1] == 0 && ret.len > 1)
ret.len--;
return ret;
}
BigNum BigNum::operator/(const int & b) const //大数对一个整数进行相除运算
{
BigNum ret;
int i,down = 0;
for(i = len - 1 ; i >= 0 ; i--)
{
ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
}
ret.len = len;
while(ret.a[ret.len - 1] == 0 && ret.len > 1)
ret.len--;
return ret;
}
int BigNum::operator %(const int & b) const //大数对一个int类型的变量进行取模运算
{
int i,d=0;
for (i = len-1; i>=0; i--)
{
d = ((d * (MAXN+1))% b + a[i])% b;
}
return d;
}
BigNum BigNum::operator^(const int & n) const //大数的n次方运算
{
BigNum t,ret(1);
int i;
if(n==0)
return 1;
if(n==1)
return *this;
int m=n;
while(m>1)
{
t=*this;
for( i=1;i<<1<=m;i<<=1)
{
t=t*t;
}
m-=i;
ret=ret*t;
if(m==1)
ret=ret*(*this);
}
return ret;
}
bool BigNum::operator>(const BigNum & T) const //大数和另一个大数的大小比较
{
int ln;
if(len > T.len)
return true;
else if(len == T.len)
{
ln = len - 1;
while(a[ln] == T.a[ln] && ln >= 0)
ln--;
if(ln >= 0 && a[ln] > T.a[ln])
return true;
else
return false;
}
else
return false;
}
bool BigNum::operator >(const int & t) const //大数和一个int类型的变量的大小比较
{
BigNum b(t);
return *this>b;
}
void BigNum::print() //输出大数
{
int i;
cout << a[len - 1];
for(i = len - 2 ; i >= 0 ; i--)
{
cout.width(DLEN);
cout.fill('0');
cout << a[i];
}
cout << endl;
}
int num[3008] ;
int main(){
int n , i , m , T ;
cin>>T ;
while(T--){
cin>>n ;
for(i = 1 ; i <= n ; i++) scanf("%d" ,&num[i]) ;
m = n - 1 ;
BigNum sum(0) , t(1) ;
BigNum sum2(0) ;
sum = sum + BigNum(num[n]) ;
for(i = 1 ; i <= m ; i++){
t = t * BigNum(m+1-i) ;
t = t / i ;
BigNum c = t * BigNum(num[n-i]) ;
if(i & 1) sum2 = sum2 + c ;
else sum = sum + c ;
}
if(sum2 > sum){
sum2 = sum2 - sum ;
putchar('-') ;
sum2.print() ;
}
else{
sum = sum - sum2 ;
sum.print() ;
}
}
return 0;
}
1010
斗地主, 模拟, 没有顺子的情况,挺好写的。
string a , b ;
int ok1(){
if(a.length() == 1) return 1 ;
if(a.length() == 2){
if(a[0] == a[1]) return 1 ;
if(a[0] == 'X' && a[1] == 'Y') return 1 ;
if(a[0] == 'Y' && a[1] == 'X') return 1 ;
}
if(a.length() == 3){
if(a[0] == a[1] && a[0] == a[2]) return 1 ;
}
if(a.length() == 4){
map<char , int> mp ; mp.clear() ;
map<char , int> ::iterator it ;
for(int i = 0 ; i < 4 ; i++) mp[a[i]]++ ;
if(mp.size() == 1) return 1 ;
if(mp.size() == 2){
it = mp.begin() ;
int c1 = it->second ;
it++ ;
int c2 = it->second ;
if(c1 < c2) swap(c1 , c2) ;
if(c1 == 3 && c2 == 1) return 1 ;
}
}
if(a.length() == 5){
map<char , int> mp ; mp.clear() ;
map<char , int> ::iterator it ;
for(int i = 0 ; i < 5 ; i++) mp[a[i]]++ ;
if(mp.size() == 2){
it = mp.begin() ;
int c1 = it->second ;
it++ ;
int c2 = it->second ;
if(c1 < c2) swap(c1 , c2) ;
if(c1 == 3 && c2 == 2) return 1 ;
}
}
if(a.length() == 6){
map<char , int> mp ; mp.clear() ;
map<char , int> ::iterator it ;
for(int i = 0 ; i < 6 ; i++) mp[a[i]]++ ;
for(it = mp.begin() ; it != mp.end() ; it++){
if(it->second == 4) return 1 ;
}
}
return 0 ;
}
int To(char c){
if(c == 'Y') return 1 ;
else if(c == 'X') return 2 ;
else if(c == '2') return 3 ;
else if(c == 'A') return 4 ;
else if(c == 'K') return 5 ;
else if(c == 'Q') return 6 ;
else if(c == 'J') return 7 ;
else if(c == 'T') return 8 ;
else if(c == '9') return 9 ;
else if(c == '8') return 10 ;
else if(c == '7') return 11 ;
else if(c == '6') return 12 ;
else if(c == '5') return 13 ;
else if(c == '4') return 14 ;
else if(c == '3') return 15 ;
}
int cnta[20] , cntb[20] ;
int ok2(){
int i , j , mxa , mxb ;
memset(cnta , 0 , sizeof(cnta)) ;
memset(cntb , 0 , sizeof(cntb)) ;
for(i = 0 ; i < a.size() ; i++) cnta[To(a[i])]++ ;
for(i = 0 ; i < b.size() ; i++) cntb[To(b[i])]++ ;
if(cnta[1] && cnta[2]) return 1 ;
if(cntb[1] && cntb[2]) return 0 ;
mxa = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cnta[i] == 4){
mxa = i ;
break ;
}
}
mxb = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cntb[i] == 4){
mxb = i ;
break ;
}
}
if(mxa != 16 && mxb == 16) return 1 ;
if(mxa ==16 && mxb != 16) return 0 ;
if(mxa != 16 && mxb != 16 && mxa < mxb) return 1 ;
if(mxa != 16 && mxb != 16 && mxa > mxb) return 0 ;
mxa = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cnta[i] == 3){
mxa = i ;
break ;
}
}
mxb = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cntb[i] == 3){
mxb = i ;
break ;
}
}
if(mxa != 16 && mxb == 16) return 1 ;
if(mxa !=16 && mxb != 16 && mxa < mxb) return 1 ;
if(mxa != 16 && mxb != 16 && mxa > mxb){
int ca = 0 ;
for(i = 3 ; i <= 15 ; i++){
if(cnta[i] >= 2 && i != mxa) ca = 1 ;
}
int cb = 0 ;
for(i = 3 ; i <= 15 ; i++){
if(cntb[i] >= 2 && i != mxb) cb = 1 ;
}
if(ca==1 && cb==0) return 1 ;
ca = 0 ;
for(i = 1 ; i <= 15 ; i++){
if(cnta[i] >= 1 && i != mxa) ca = 1 ;
}
cb = 0 ;
for(i = 1 ; i <= 15 ; i++){
if(cntb[i] >= 1 && i != mxb) cb = 1 ;
}
if(ca==1 && cb==0) return 1 ;
}
mxa = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cnta[i] >= 2){
mxa = i ;
break ;
}
}
mxb = 16 ;
for(i = 3 ; i <= 15 ; i++){
if(cntb[i] >= 2){
mxb = i ;
break ;
}
}
if(mxa != 16 && mxb == 16) return 1 ;
if(mxa !=16 && mxb != 16 && mxa < mxb) return 1 ;
mxa = 16 ;
for(i = 1 ; i <= 15 ; i++){
if(cnta[i] >= 1){
mxa = i ;
break ;
}
}
mxb = 16 ;
for(i = 1 ; i <= 15 ; i++){
if(cntb[i] >= 1){
mxb = i ;
break ;
}
}
if(mxa != 16 && mxb == 16) return 1 ;
if(mxa !=16 && mxb != 16 && mxa < mxb) return 1 ;
return 0 ;
}
int main(){
int t ;
cin>>t ;
while(t--){
cin>>a>>b ;
if(ok1()){ puts("Yes") ; continue ;}
if(ok2()) puts("Yes") ;
else puts("No") ;
}
return 0 ;
}