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组成的栈,这个程序的元素有两种语义:

10表示压出栈顶两个整数,求和后再压入栈;

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种选择,删除余数0123

f[i][j][k][t]表示有能否删除到剩余i个余数是3j个余数是2k个余数是1t个余数是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;
        } 
        
}; 

 

 

 

 

转载于:https://www.cnblogs.com/xchaos/archive/2012/08/27/2657964.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值