SRM 553 DIV2
250pt
题意:
鸡兔同笼类问题,求三种动物总数。
分析:
第二个变量完全没用,直接推公式可以跳过个数求总数。
View Code
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <iomanip> #include <bitset> #include <list> using namespace std; #define REP(i,n) for(i=0;i<(n);++i) #define FOR(i,l,h) for(i=(l);i<=(h);++i) #define FORD(i,h,l) for(i=(h);i>=(l);--i) typedef vector<int> VI; typedef vector<double> VD; typedef long long LL; class PlatypusDuckAndBeaver { public: int minimumAnimals(int webbedFeet, int duckBills, int beaverTails) { return webbedFeet/2-beaverTails; } };
500pt
题意:
一个由整数组成的程序和一个已有无限个0组成的栈,这个程序的元素有两种语义:
1,0表示压出栈顶两个整数,求和后再压入栈;
2,非0表示该元素入栈;
给定一段含有一个未知元素的程序和该程序执行完后栈顶元素,求未知元素。
分析:
因为有两种语义,所以分别枚举两种情况,再与结果比较。
枚举非0时,又考虑考虑两种情况,在计算栈顶元素的过程中有没有用到未知量。
PS.比赛的时候犯了两个错误:
以为栈顶元素一定会用到未知量;
数据溢出,没用long long;
有人在枚举非0时居然用二分答案,好方法......简单,粗暴。
View Code
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <iomanip> #include <bitset> #include <list> using namespace std; #define REP(i,n) for(i=0;i<(n);++i) #define FOR(i,l,h) for(i=(l);i<=(h);++i) #define FORD(i,h,l) for(i=(h);i>=(l);--i) typedef vector<int> VI; typedef vector<double> VD; typedef long long LL; class Suminator { public: int findMissing(vector <int> a, int m) { int i,j,k,n=(int)a.size(); bool used=false; long long s[211]={0}; k=60; for(i=0;i<n;i++) if(a[i]<=0) { k--; s[k-1]+=s[k]; } else s[k++]=a[i]; if(s[k-1]==m) return 0; if(a[n-1]==-1) return m; memset(s,0,sizeof(s)); k=60; for(i=0;a[i]+1;i++) if(a[i]==0) { k--; s[k-1]+=s[k]; } else s[k++]=a[i]; j=k; s[k++]=0; for(i++;i<n;i++) if(a[i]==0) { k--; if(k==j||k-1==j) j=k-1; s[k-1]+=s[k]; } else s[k++]=a[i]; if(k-1!=j) return s[k-1]==m?1:-1; long long ret=m-s[k-1]; if(ret<1||ret>1000000000) return -1; return (int)ret; } };
1000pt
题意:
给定一个整数数组,求删除k个数后,剩余数的和的最大值,在删除过程剩余和中不能被4整除。
分析:
易知,要使剩余和最大,对除4余数相同的数,有大不删小,如有8在情况下是不会删除4的,所以每次删除一个数时,相当于只有4种选择,删除余数0或1或2或3。
f[i][j][k][t]表示有能否删除到剩余i个余数是3,j个余数是2,k个余数是1,t个余数是0。易得f[i][j][k][t]=f[i+1][j][k][t]||f[i][j+1][k][t]||f[i][j][k+1][t]||f[i][j][k][t+1]。
View Code
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <iomanip> #include <bitset> #include <list> using namespace std; #define REP(i,n) for(i=0;i<(n);++i) #define FOR(i,l,h) for(i=(l);i<=(h);++i) #define FORD(i,h,l) for(i=(h);i>=(l);--i) typedef vector<int> VI; typedef vector<double> VD; typedef long long LL; #define MAXN 51 bool f[MAXN][MAXN][MAXN][MAXN]; class SafeRemoval { public: int removeThem(vector <int> s, int kk) { int i,j,k,t,n,l[4],ret=-1; VI a[4]; n=s.size(); for(i=0;i<n;i++) a[s[i]%4].push_back(-s[i]); for(i=0;i<4;i++) sort(a[i].begin(),a[i].end()),l[i]=a[i].size(); memset(f,false,sizeof(f)); f[l[3]][l[2]][l[1]][l[0]]=true; for(i=l[3];i>=0;i--) for(j=l[2];j>=0;j--) for(k=l[1];k>=0;k--) if((i*3+2*j+k)%4) for(t=l[0];t>=0;t--) if(i+j+k+t<n) { f[i][j][k][t]=f[i+1][j][k][t]||f[i][j+1][k][t] ||f[i][j][k+1][t]||f[i][j][k][t+1]; } kk=n-kk; int sum[4][55]; for(i=0;i<4;i++) { sum[i][0]=0; for(j=0;j<l[i];j++) sum[i][j+1]=sum[i][j]-a[i][j]; } for(i=0;i<=l[3];i++) for(j=0;j<=l[2];j++) for(k=0;k<=l[1];k++) if(i+j+k<=kk&&f[i][j][k][kk-i-j-k]) { ret=max(sum[3][i]+sum[2][j]+sum[1][k]+sum[0][kk-i-j-k],ret); } return ret; } };