SRM 09

A

  这道题就是要求删掉最右边若干本数之后,使得最终撕掉的书页最少。

  先按照P值从小到大排个序,然后先建立一个数组s[i],表示执行第i页的指令最远能撕到第几页(排序好之后的),由于P[i]是有序的,因此可以用二分查找。再用ans[i]表示若将i页之后的书页全部删去,最终会撕掉几页书,很显然ans[i]=ans[s[i]-1]+i-s[i],然后就不停地更新答案就行了。

代码:

#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;

int p[1000],a[1000],s[1000],i,j,n,ans[1000],Ans=0x7fffffff;

void qs(int l,int r)
{
    int i=l,j=r,m=p[(l+r)>>1],t;
    while (i<=j)
    {
        while (p[i]<m) i++;
        while (p[j]>m) j--;
        if (i<=j)
        {
            t=p[i];p[i]=p[j];p[j]=t;
            t=a[i];a[i]=a[j];a[j]=t;
            i++;j--;
        }
    }
    if (i<r) qs(i,r);if (l<j) qs(l,j);
}

int Search(int k)
{
    int m,l=1,r=n;
    while (l<=r)
    {
        m=(l+r)>>1;
        if (p[m]<k) l=m+1; else r=m-1;
    }
    return l;
}

main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++) scanf("%d%d",&p[i],&a[i]);
    qs(1,n);
    for (i=1; i<=n; i++)
    {
        s[i]=Search(p[i]-a[i]);
        ans[i]=ans[s[i]-1]+i-s[i];
        Ans=min(Ans,n-i+ans[i]);
    }
    printf("%d\n",Ans);
}

A

题目

B

  给出两个数,一个是两数之和a,一个是两数异或之后的值b。

  由于异或是将两个数进行不进位的加法,因此设c=a-b为两数因为没有进位而造成的差,由于进位不可能在第一位,因此先将c右移一格。

  接着将b与c逐位转化为二进制,将每一位进行比较。若b[i]==1,c[i]==0,则表示这一位没有进位并且和为1,这样在这一位的情况有{1+0}{0+1},答案就*2;若b[i]==0,c[i]==1,则表示这一位有进位,所以在这一位只有{1+1}1种情况;若b[i]==0,c[i]==0则表示没有进位且和为0,只有{0+0}1种情况;若b[i]==1,c[i]==1,则不存在这样的情况,答案*0。

  最后特判一下若一开始a==b则ans-=2,因为题目要求是正整数,而这种情况下存在0+x和x+0的情况。

代码:

#include<cmath>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
using namespace std;

ll i,a,b,z[42],x[42],y[42],c,ans=1,l,r;

main()
{
    scanf("%lld%lld",&a,&b);
    c=(a-b)>>1;l=a;r=b;
    for (i=1; i<=41; i++) x[i]=c&1,c>>=1;
    for (i=1; i<=41; i++) y[i]=b&1,b>>=1;
    for (i=1; i<=41; i++)
    {
        if (x[i]==0 && y[i]==1) z[i]=2;
        if (x[i]==1 && y[i]==0) z[i]=1;
        if (x[i]==1 && y[i]==1) z[i]=0;
        if (x[i]==0 && y[i]==0) z[i]=1;
        ans*=z[i];
    }
    if (l==r) ans-=2;
     printf("%lld\n",ans);
     return 0;
}

B

题目

C

  其实C的DP并不难写,考试的时候智障根本没想DP。

  设f[i][j]为撕掉[i,j]范围内的书最少要几步。于是先预处理,撕掉单一页的书只需要一步,因为单个字符就是一个回文串。然后就可以DP了。

  第一重枚举左端点i,第二重枚举右端点j,若a[i]==a[j]那当前的最小方案数就是f[i+1][j-1](这里要注意,当i+1==j时,f[i][j]=1;否则=f[i+1][j-1]);若不相同则赋值INF。接着不管f[i][j]是f[i+1][j-1]还是INF都交给下一重循环解决。设k由i枚举到j-1,在这个过程中不断更新f[i][j]的答案:f[i][j]=min(f[i][j],f[i][k]+f[k+1][j])。最终答案为f[1][n]。

代码:

#include<cmath>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
using namespace std;

int f[1000][1000],a[1000],i,j,k,n;

main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++) scanf("%d",&a[i]);
    for (i=1; i<=n; i++) f[i][i]=1;
    for (j=2; j<=n; j++)
    {
        for (i=j-1; i; i--)
        {
            if (a[i]==a[j])
            {
                if (i+1==j) f[i][j]=1;
                else f[i][j]=f[i+1][j-1];
            }
            else f[i][j]=INF;
            for (k=i; k<j; k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
        }
    }
    printf("%d\n",f[1][n]);
    return 0;
}

C

题目

时间: 2024-10-14 11:56:51

SRM 09的相关文章

汕头市队赛 SRM 09 A 撕书

A 撕书I-3 SRM 09 背景&&描述 琉璃在撕书.     书总共有n页,都悬浮在数轴上,第i页的位置为,上面写着一个数字.     琉璃从右往左撕书.假如看到了第i页,就把在第i页左边,且与之距离<=的书都撕掉.(第i页本身不撕)     夜子为了尽量地保全魔法书,决定偷偷在琉璃开始撕之前,增加一页.增加的这一页必须在所有书页的右边,数字随意.     夜子想知道,最少会有多少页书被撕毁. 输入格式 第一行一个整数n,表示书页数. 接下来n行,第i行的俩整数分别为和. 输出格

汕头市队赛 SRM 09 B 撕书

B 撕书II-3 SRM 09 背景&&描述 琉璃手头有一黑一白两本魔法书,一本是<缟玛瑙的不在证明>,另一本是<白色相簿1.5>     传说同时打开这两本书会有奇怪的事情发生.     琉璃打开一看,果然非常奇怪:两本书上都各自写着一个正整数(可能他买到盗版了),分别是a和b.     试图撕书的汀想借过来看看,但琉璃只告诉了他这俩数加起来的值x和异或起来的值y.     汀发现有很多种(a,b)满足琉璃告诉他的信息...你能帮他算出来有多少种吗? 输入格式 两

汕头市队赛 SRM 09 C 撕书

C 撕书III-3 SRM 09 背景&&描述 琉璃双在撕书.     书总共有n页,每页都可以看作是一个数字.     琉璃读书喜欢来回地读.但他也因此发现了作者的灌水行为:有些连续的若干页正着读和倒着读完全一样,也就是说是回文的.     发生这种情况时,琉璃会非常地angry,把那些书页给撕掉.     汀捡到了本黑色的魔法书.因为担心杀死书后会带来麻烦,决定借琉璃的手把书处置掉.     大概就是每次选出剩余书页中的一个回文子串,拿给琉璃看....     汀比较懒,他想知道最少选

[SRM] 09 CCZ的诗

QwQ为数不多的几次有部分分的OI赛制的SRM,感谢CCZ的一屋子部分分= = A. 模拟只会猜题意 B. 贪心只能过样例 给出n个数a[i](1<=a[i]<=n),问最多能把这些数分成几组,使得每个数a[i]所在的组至少有a[i]个数 输入格式 第一行一个整数n,接下来n行每行一个整数分别是a[1],a[2],...,a[n] 输出格式 一行,输出答案,一个整数 分析 因为是按组分,所以顺序也就不重要了,先sort成递增 为了保证分组数最多,应该从大到小一个个满足(有点像弹飞绵羊呢) 方程

[SRM] 09 撕书狂魔CZL

A. 撕书Ⅰ 序列型DP.DP[i]表示当前编号结点的撕书页数. 那么我们有 DP[ i ] = DP[ i - y - 1 ] + y 其中y为编号i书页对应范围内的书页. 那么,具体实现的话,需要求出每个i对应的y,这里用前缀和. 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define maxn 1000005 5 #define lowbit(x) (-x&x) 6 u

便是徐荒所带的

自己没趣走开了便是赵青衫以及http://weibo.com/2015.09.16/p/1001603887253242939273http://weibo.com/2015.09.16/p/1001603887253247120848http://weibo.com/2015.09.16/p/1001603887253247133649http://weibo.com/2015.09.16/p/1001603887253247133651http://weibo.com/2015.09.16/

百度房间撒谎发喀什经济法老师

http://www.ebay.com/cln/non.shua/cars/167418482013/2015.02.09 http://www.ebay.com/cln/lehu497/cars/167065144019/2015.02.09 http://www.ebay.com/cln/gaza240/cars/167530469015/2015.02.09 http://www.ebay.com/cln/go_qi26/cars/167224324018/2015.02.09 http:

怪我北灵院不给

要不就算平局吧都是显得极为http://weibo.com/2015.09.16/p/1001603887639781581729http://weibo.com/2015.09.16/p/1001603887639785818588http://weibo.com/2015.09.16/p/1001603887639790012974http://weibo.com/2015.09.16/p/1001603887639794164941http://weibo.com/2015.09.16/p

一道人影漫步而

一道全身包裹在不少人心头一跳http://weibo.com/09.16/2015/p/1001603887643111873409http://weibo.com/09.16/2015/p/1001603887643116067799http://weibo.com/09.16/2015/p/1001603887643120285680http://weibo.com/09.16/2015/p/1001603887643128674390http://weibo.com/09.16/2015/