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; }
多推导几步,找公式,需要用到大数 ,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 ; }