cf 301 div2

A - Combination Lock

题目大意:给有n个(0-9)环圈密码锁,数串 s1->s2最少移动次数;

题目分析:

简单模拟;

代码:

const int N=100007;

char s1[N],s2[N];

int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        int ans=0;
        scanf("%s%s",s1+1,s2+1);
        for(int i=1;i<=n;i++)
        {
            int a=s1[i]-'0';
            int b=s2[i]-'0';
            if(a>b) swap(a,b);
            ans+=min(b-a,a+(9-b)+1);
        }
        printf("%d\n",ans);
    }
    return 0;
}

B - School Marks

题目大意:n个数,已知其中 k个;已知中位数>=y;且所有数sum<=x;填剩下n-k个数;

题目分析:

因为sum要小于x,所以尽量填小数。 mid左边填1,右边填y;

代码:

vector<int> ans;
int main()
{
    int n,k,p,x,y;
    while(scanf("%d%d%d%d%d",&n,&k,&p,&x,&y)==5)
    {
        ans.clear();
        int sum=0;
        int mi=0;
        int flag=0;
        for(int i=0;i<k;i++)
        {
            int v;cin>>v;
            if(v>=y) flag++;
            if(v<y) mi++;
            sum+=v;
        }
        if(mi>n/2||sum>x){
            printf("-1\n");
            continue;
        }
        while(n/2+1-(k-mi)<0&&flag>1){
            mi++;
            flag--;
        }
        for(int i=0;i<n/2-mi;i++){
            ans.push_back(1);
            sum+=1;
        }
        for(int i=0;i<n/2+1-(k-mi);i++)
        {
            ans.push_back(y);
            sum+=y;
            flag=1;
        }
        if(sum<=x&&flag&&(signed int)ans.size()+k==n){
            for(int i=0;i<(signed int)ans.size();i++){
                if(!i) printf("%d",ans[i]);
                else
                    printf(" %d",ans[i]);
            }
            printf("\n");
        }
        else{
            printf("-1\n");
        }

    }
    return 0;

}

C - Ice Cave

题目大意:给迷宫,X不能走,‘ . ‘走两次,从(r1,c2)--->(r2,c2)要求(r2,c2)走两次;

题目分析:

dfs,cnt记录次数,(好吧,我是用的还标记,’*‘表示已经走了一遍);

代码:

const int N=100007;

char gra[555][555];
int go[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
int r1,c1,r2,c2;
int ok;
int n,m;
void dfs(int cx,int cy)
{
    int x,y;
    if(ok) return;
    for(int i=0;i<4;i++)
    {
        x=cx+go[i][0];
        y=cy+go[i][1];
        if(1<=x&&x<=n&&1<=y&&y<=m)
        {
            if(gra[x][y]!='X'){

                if(gra[x][y]=='*'){
                    if(x==r2&&y==c2)
                        ok=1;
                }
                else{
                    gra[x][y]='*';
                    dfs(x,y);
                    //gra[x][y]='.';
                }

            }
        }
    }
}

int main()
{

    while(scanf("%d%d",&n,&m)==2)
    {
        ok=0;
        for(int i=1;i<=n;i++)
            scanf("%s",&gra[i][1]);
        scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
        if(gra[r2][c2]=='X') gra[r2][c2]='*';
        dfs(r1,c1);
        if(ok) printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

/*
4 6
X...XX
...XX.
.X..X.
.....X
1 6
4 6
*/

D - Bad Luck Island

题目大意:初始3物种:r个石头,s个剪刀,p个布;任意一对碰面的概率是相等的(不考虑,同种碰面);求最后只剩下一个物种的概率;

题目分析:

概率知识,假如当前存在(石头,剪刀,布):(i,j,k);那么下一步如果挂了石头(i-1,j,k),那么概率是 dp[ i ][ j ][ k ] * ( i * k ) /( i * k + i * j + j * k);

其它同理;

代码:

const int N=100007;

double dp[110][110][110];
int main()
{
    int r,s,p;
    while(scanf("%d%d%d",&r,&s,&p)==3)
    {

        for(int i=0;i<=r;i++){
            for(int j=0;j<=s;j++){
                for(int k=0;k<=p;k++){
                    dp[i][j][k]=0.0;
                }
            }
        }
        dp[r][s][p]=1.0;
        for(int i=r;i>=0;i--){
            for(int j=s;j>=0;j--){
                for(int k=p;k>=0;k--){
                    if((i==0&&j==0&&k==0)) continue;
                    if(((i+1)*k+j*k+(i+1)*j)>0) //保证,这一转移能成立,分母不为0;
                        dp[i][j][k]+=1.0*(dp[i+1][j][k]*(i+1)*k)/((i+1)*k+j*k+(i+1)*j);
                    if(((j+1)*i+i*k+(j+1)*k)>0)
                        dp[i][j][k]+=1.0*(dp[i][j+1][k]*(j+1)*i)/((j+1)*i+i*k+(j+1)*k);
                    if((i*j+i*(k+1)+j*(k+1))>0)
                        dp[i][j][k]+=1.0*(dp[i][j][k+1]*(k+1)*j)/(i*j+i*(k+1)+j*(k+1));
                    //cout<<dp[i][j][k]<<endl;
                }
            }
        }
        double a=0.0,b=0.0,c=0.0;
        for(int i=1;i<=r;i++) a+=dp[i][0][0];
        for(int j=1;j<=s;j++) b+=dp[0][j][0];
        for(int k=1;k<=p;k++) c+=dp[0][0][k];
        printf("%.12f %.12f %.12f\n",a,b,c);
    }
    return 0;
}

//cf!!!!!!!!何时div1!!!

时间: 2024-10-06 09:55:18

cf 301 div2的相关文章

CF #261 div2 D. Pashmak and Parmida&amp;#39;s problem (树状数组版)

Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partner to be clever too (although he's not)! Parmida has prepared the following test problem for Pashmak. There is a sequence a that consists of n

CF #261 DIV2 A,B,C,D

A 先判断邻边长度是否相等,不是就无法构成正方形,否则的话位置坐标搞一下 #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <algorithm> #include <bitset> #include <vector> #include <set>

CF#215 DIV2: B. Sereja and Suffixes

Sereja has an array a, consisting of n integers a1, a2, ..., an. The boy cannot sit and do nothing, he decided to study an array. Sereja took a piece of paper and wrote out m integers l1,?l2,?...,?lm (1?≤?li?≤?n). For each number li he wants to know

cf#261 div2 解题报告

.....代码没什么可说的,主要是学习各路大神姿势 A题 化简化简水题,都告诉平行坐标轴了,数据还出了对角线,后面两个点坐标给的范围也不错 ........和最优代码相比姿势有点混乱 #include <cstdio> int x[4],y[4]; int abs(int n){ return n<0?-n:n; } int main(){ scanf("%d%d%d%d",x,y,x+1,y+1); int dx=abs(x[0]-x[1]); int dy=abs

CF R631 div2 1330 E Drazil Likes Heap

LINK:Drazil Likes Heap 那天打CF的时候 开场A读不懂题 B码了30min才过(当时我怀疑B我写的过于繁琐了. C比B简单多了 随便yy了一个构造发现是对的.D也超级简单 dp了一下就没了. 但是到E就只剩下30min(都怪A B浪费我过多时间. 观察题目中给的一个程序 其维护了一个大根堆且这个程序意思是一个函数 这个函数是指对于这个大根堆上的一个非空节点来说每次会将这个值给删掉继承最大的儿子值 然后递归值最大的儿子值得某个节点没有一个非空儿子(那么这个点的值被删掉为0.

CF 313 DIV2 B 树状数组

http://codeforces.com/contest/313/problem/B 题目大意 给一个区间,问你这个区间里面有几个连续相同的字符. 思路: 表示个人用树状数组来写的...了解了树状数组的本质就行了. 当然用sum[r]-sum[l]也是可以的

CF #327 DIV2 D、E

两题都不难. 对于D题,可以使用相对移动,把吹aircraft移动变成相反方向的待援点的移动.假设此时时间为t,把aircraft的速度设为Vmax,看待援点在飞船最大速度飞行t秒的范围内,注意风向变化的时间点即可.其实很明显的二分.. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7

CF R274 Div2 E Riding in a Lift DP

先预处理出能到当前点的区间,然后通过前缀和求得当前值即可. #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <climits> #include <iostream> #include &

CF#345 div2 A\B\C题

A题: 贪心水题,注意1,1这组数据,坑了不少人 #include <iostream> #include <cstring> using namespace std; int main() { int a1,a2; while(cin>>a1>>a2) { int i=0; int b = max(a1,a2); int s = min(a1,a2); if(b==1 && s==1) { cout<<0<<endl