Codeforces Round #336 (Div. 2) (4/5)

来源:互联网 发布:正版office办公软件 编辑:程序博客网 时间:2024/06/06 15:43
亲妈爆炸啊。
只看了3个题。感觉智商受到了严重的打击和摧残。手速也不够啊




A题。想了10分钟。


就是一个电梯从顶部往底部,一层楼一分钟。有的楼层有人要s分钟上到电梯里面,

求电梯搭载所有人到底部的最短时间。

贪心水题。

代码:

#include <iostream>#include <map>#include <algorithm>#include <bitset>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <stack>#include <functional>#include <set>#include<sstream>#include <cmath>using namespace std;#define pb push_back#define PB pop_back#define bk back()#define fs first#define se second#define INF 1e9+100;#define sq(x) (x)*(x)#define eps (1e-10)#define clr(x) memset((x),0,sizeof (x))#define cp(a,b) memcpy((a),(b),sizeof (b))const int maxn=100100;int main(){    int n,s;    cin>>n>>s;    int cnt=0;    for(int i=1;i<=n;i++)    {        int a,b;        cin>>a>>b;        cnt=max(cnt,max(s-a,b)+a);    }    cout<<cnt<<endl;    return 0;}

B题。亲妈爆炸......


给你2个字符串a,b。由0 1组成。


a的长度小于b的长度,在b中选出连续的长度与a相同的字符串,记录不相同的个数和。。。


首先看别人10分钟内搞出来了,肯定不是暴力枚举。


卡了很久很久。
然后发现对于每个a中的字符,找b中要比较的长度,一一比较,求和。
额。思路对了、
TLE。


后来优化。预处理b中的0和1的前缀和。
然后再进行比较
很好WR9;


后来在讨论时发现要long long。。。。。


代码:

#include <iostream>#include <map>#include <algorithm>#include <bitset>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <stack>#include <functional>#include <set>#include<sstream>#include <cmath>using namespace std;#define pb push_back#define PB pop_back#define bk back()#define fs first#define se second#define INF 1e9+100;#define sq(x) (x)*(x)#define eps (1e-10)#define clr(x) memset((x),0,sizeof (x))#define cp(a,b) memcpy((a),(b),sizeof (b))const int maxn=200100;int sum0[maxn];int main(){    string a,b;    cin>>a;    cin>>b;    long long sum=0;    int lena=a.length();    int lenb=b.length();    for(int i=0;i<lenb;i++)    {        if(!i) sum0[i]=(b[i]=='0'?1:0);        else        sum0[i]=sum0[i-1]+(b[i]=='0'?1:0);    }    for(int i=0;i<lena;i++)    {        if(!i)        {            for(int j=0;j<=lenb-lena;j++)            if(a[i]!=b[j]) sum++;            continue;        }        int k=lenb-(lena-i);        sum+=(a[i]=='1'?sum0[k]-sum0[i-1]:k-i+1-(sum0[k]-sum0[i-1]));    }    cout<<sum<<endl;    return 0;}

C题 时间不够。


给你一条线上的n个位置的炸弹,每个位置有1个范围p。从右到左,依次点燃每个炸弹,范围以内的炸弹也会被间接引爆,之后不能引爆,在右边随意加个随意范围的炸弹。求在此条件下,间接引爆炸弹的最小数目。




也想了很久很久
后来发现是递推。由第一个往后面进行递推。然后略微处理一下即可。
但是时间不够,明天再测试一下。


....发现TLE了


发现自己超时的原因是在一个循环里面再满足a[i]-b[i]的寻找上费了时间。。因为CF数据BT。所以可以理解为o(n^2)的复杂度。


后来看了题解发现可以用动态规划做。


动态规划时间的状态的定义跟我的不同,定义的是能不爆炸的灯塔树。ORZ。这样就避免满足条件的寻找了.......智商捉急。。。


代码:

#include <iostream>#include <map>#include <algorithm>#include <bitset>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <stack>#include <functional>#include <set>#include<sstream>#include <cmath>using namespace std;#define pb push_back#define PB pop_back#define bk back()#define fs first#define se second#define INF 1e9+100;#define sq(x) (x)*(x)#define eps (1e-10)#define clr(x) memset((x),0,sizeof (x))#define cp(a,b) memcpy((a),(b),sizeof (b))const int maxn=1001000;int b[maxn],cnt[maxn];int main(){    clr(cnt);    clr(b);    int T;    cin>>T;    for(int i=0;i<T;i++)    {        int a;        cin>>a;        cin>>b[a];    }    if(b[0]>0) cnt[0]=1;    int MAX=0;    for(int i=1;i<maxn;i++)    {        if(b[i]==0) cnt[i]=cnt[i-1];        else        {            if(b[i]>=i) cnt[i]=1;            else cnt[i]=cnt[i-b[i]-1]+1;        }        MAX=max(MAX,cnt[i]);    }    cout<<T-MAX<<endl;    return 0;}

D题


如果当时看了题目的话,可以感觉到是个区间dp。。。
知道了枚举空间长度,但是完全下不了手。后来看别人的题解。发现了入手点。
定义状态dp[i][j] 表示区间[i,j]至少需要多少次数完成。
-----------------------------------------------------------------------------------
i>j 为0
i==j为1;
i+1==j时 dp[i][j]=2或者1。根据相等不相等来判断。。
否则。。。
对于最左边的点。要么自己单独出去... 1+dp[i+1][j]
要么跟i+1到j中的一个相同的元素匹配,假定是k dp[i+1][k-1]+dp[k+1][j]  i<k<j.......
------------------------------------------------------------------------------------
很好地发现上述思路错了。c[i]==c[i+1]是需要特判的
不然样例3 中的dp[i+1][k-1]+dp[k+1][j]就过不去了。。。。。。。。。。。。。。。。

代码:

#include <iostream>#include <map>#include <algorithm>#include <bitset>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <stack>#include <functional>#include <set>#include<sstream>#include <cmath>using namespace std;#define pb push_back#define PB pop_back#define bk back()#define fs first#define se second#define INF 1e9+100;#define sq(x) (x)*(x)#define eps (1e-10)#define clr(x) memset((x),0,sizeof (x))#define cp(a,b) memcpy((a),(b),sizeof (b))const int maxn=510;int c[maxn];int dp[maxn][maxn];int main(){    int T;    cin>>T;    for(int i=0;i<T;i++)    cin>>c[i];    for(int i=0;i<T;i++)    for(int j=0;j<T;j++)    {        if(i>j) dp[i][j]=0;        else if(i==j) dp[i][j]=1;        else dp[i][j]=INF;    }    if(T<2) cout<<dp[0][T-1]<<endl;    else    {        for(int k=1;k<T;k++)        {            for(int i=0;i+k<T;i++)            {                dp[i][i+k]=min(dp[i][i+k],1+dp[i+1][i+k]);                if(c[i]==c[i+1]) dp[i][i+k]=min(1+dp[i+2][i+k],dp[i][i+k]);                for(int j=i+2;j<=i+k;j++)                {                if(c[i]==c[j])                dp[i][i+k]=min(dp[i+1][j-1]+dp[j+1][i+k],dp[i][i+k]);                }            }        }        cout<<dp[0][T-1]<<endl;    }    return 0;}


E题

看懂了题目发现并不会做。。。。题解说是字符串,kmp,然而并不会。


题解地址: 点击打开链接

0 0
原创粉丝点击