• codeforces #301 div2


    A:简单题

    每次判断向上转快,还是向下转快即可

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    using namespace std;
    #define N 10005
    #define ll long long
    char s1[N] , s2[N];
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int n;
        while(~scanf("%d" , &n))
        {
            scanf("%s%s" , s1 , s2);
            int ans=0;
            for(int i=0 ; i<n ; i++){
                int a=s1[i]-'0';
                int b=s2[i]-'0';
                if(a>b){
                    int t=a;
                    a=b;
                    b=t;
                }
                ans += min(b-a , 10+a-b);
            }
            printf("%d
    " , ans);
        }
        return 0;
    }
    View Code

    B:贪心

    先判断所给的数中能否已经保证中位数大于y,不能的话,添加尽可能少的y使其满足中位数为y,剩下的值全定为1,判断总和是否超过x

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    using namespace std;
    #define N 10005
    #define ll long long
    int n,k,p,x,y;
    int a[N];
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int n;
        while(~scanf("%d%d%d%d%d" , &n,&k,&p,&x,&y))
        {
            int pos = (n+1)/2;
            int cnt1 = 0 , cnt2=0;
            int sum=0;
            for(int i=1 ; i<=k ; i++){
                scanf("%d" , &a[i]);
                if(a[i]>=y) cnt1++;
                else cnt2++;
                sum+=a[i];
            }
    
            if(cnt1>n-pos){
                for(int i=k+1 ; i<=n ; i++) a[i]=1,sum++;
                if(sum<=x){
                    for(int i=k+1 ; i<=n ; i++){
                        if(i<n) printf("%d " , a[i]);
                        else printf("%d
    " , a[i]);
                    }
                }
                else{
                    puts("-1");
                }
            }else{
                bool flag=true;
                if(pos-cnt1>n-k) flag=false;
                else{
                    int i;
                    for(i=k+1 ; i<=k+pos-cnt1 ; i++){
                        a[i] = y;
                        sum+=a[i];
                    }
                    for(;i<=n;i++){
                        a[i]=1;
                        sum+=a[i];
                    }
                    if(sum>x) flag=false;
                }
                if(flag){
                    for(int i=k+1 ; i<=n ; i++){
                        if(i<n) printf("%d " , a[i]);
                        else printf("%d
    " , a[i]);
                    }
                }
                else puts("-1");
            }
        }
        return 0;
    }
    View Code

    C:bfs

    从起点bfs,判断能否有两条路径到达终点即可

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    using namespace std;
    #define N 1005
    #define ll long long
    int n , m;
    int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    
    struct Point{
        int x,y;
        Point(int x=0 , int y=0):x(x),y(y){}
    }p[N][N];
    int mat[N][N];
    char s[N][N];
    Point st , en;
    queue<Point> q;
    
    bool ok(int x , int y)
    {
        return x>0 && x<=n && y>0 && y<=m;
    }
    
    bool bfs()
    {
        while(!q.empty()) q.pop();
        q.push(st);
        while(!q.empty())
        {
            Point u = q.front();
            q.pop();
            for(int i=0 ; i<4 ; i++){
                int xx = u.x+dir[i][0];
                int yy = u.y+dir[i][1];
                if(!ok(xx,yy)) continue;
                if(mat[xx][yy]==0){
                    mat[xx][yy]=-1;
                  //  cout<<"in: "<<u.x<<" "<<u.y<<" to: "<<xx<<" "<<yy<<endl;
                    q.push(Point(xx,yy));
                }
                else if(mat[xx][yy]==-1 && xx==en.x && yy==en.y){
                  //  cout<<"in: "<<u.x<<" "<<u.y<<endl;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
      //  freopen("a.in" , "r" , stdin);
    
        while(~scanf("%d%d" , &n,&m))
        {
            for(int i=1 ; i<=n ; i++)
                scanf("%s" , s[i]+1);
            for(int i=1 ; i<=n ; i++){
                for(int j=1 ; j<=m ; j++){
                    if(s[i][j] == '.'){
                        mat[i][j]=0;
                    }
                    else mat[i][j]=-1;
                }
            }
    
            scanf("%d%d" , &st.x , &st.y);
            scanf("%d%d" , &en.x , &en.y);
    
            printf("%s
    " , bfs()?"YES":"NO");
        }
        return 0;
    }
    View Code

    D:概率DP

    dp[i][j][k] 表示剩余i个rock,j个siccsors,k个paper时的概率

    初始dp[r][q][s]=1

    状态转移

    dp[i][j][k]+=dp[i+1][j][k]*(1.0*(i+1)*k/((i+1)*j+(i+1)*k+k*j));
    dp[i][j][k]+=dp[i][j+1][k]*(1.0*(j+1)*i/(i*(j+1)+i*k+(j+1)*k));
    dp[i][j][k]+=dp[i][j][k+1]*(1.0*(k+1)*j/(i*j+i*(k+1)+j*(k+1)));

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    using namespace std;
    #define N 210
    #define ll long long
    
    double dp[N][N][N];
    int r,s,q;
    
    void solve()
    {
        memset(dp,0,sizeof(dp));
        dp[r][s][q]=1.0;
        for(int i=r ; i>=0 ; i--){
            for(int j=s ; j>=0 ; j--){
                for(int k=q ; k>=0 ; k--){
                    if(i==r && j==s && k==q) continue;
                    dp[i][j][k] = 0;
                    if(k) dp[i][j][k]+=dp[i+1][j][k]*(1.0*(i+1)*k/((i+1)*j+(i+1)*k+k*j));
                    if(i) dp[i][j][k]+=dp[i][j+1][k]*(1.0*(j+1)*i/(i*(j+1)+i*k+(j+1)*k));
                    if(j) dp[i][j][k]+=dp[i][j][k+1]*(1.0*(k+1)*j/(i*j+i*(k+1)+j*(k+1)));
                  //  cout<<i<<" "<<j<<" "<<k<<" "<<dp[i][j][k]<<endl;
                }
            }
        }
    }
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
    
        while(~scanf("%d%d%d" , &r,&s,&q))
        {
            solve();
            double ans1=0 , ans2=0 , ans3=0;
            for(int i=1 ; i<=r ; i++) ans1+=dp[i][0][0];
            for(int i=1 ; i<=s ; i++) ans2+=dp[0][i][0];
            for(int i=1 ; i<=q ; i++) ans3+=dp[0][0][i];
            printf("%.11f %.11f %.11f
    " , ans1 , ans2 , ans3);
        }
        return 0;
    }
    View Code

    E:线段树

    将点离散化后保存到线段树上,那么最多有200000个点

    逐个添加,判断离散化的点之间可以形成多少对

    在计算每个离散化的点和其他非离散化的区间内的点形成了多少对

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 200010
    #define ls o<<1
    #define rs o<<1|1
    #define define_m int m=(l+r)>>1
    #define ll long long
    int a[N*2] , k , p[N] , q[N] , val[N*2];
    ll sum[N<<2];
    ll ans=0;
    
    int getIndex(int key)
    {
        return lower_bound(a , a+k , key)-a;
    }
    
    void push_up(int o)
    {
        sum[o] = sum[ls]+sum[rs];
    }
    
    void update(int o , int l , int r , int pos)
    {
        if(l==r && l==pos){
            sum[o]++;
            return ;
        }
        define_m;
        if(m>=pos) update(ls , l , m , pos);
        else update(rs , m+1 , r , pos);
        push_up(o);
    }
    
    int query(int o , int l , int r , int s , int t)
    {
        if(l>r) return 0 ;
        if(l>=s && r<=t){
            return sum[o];
        }
        int ans=0;
        define_m;
        if(m>=s) ans+=query(ls , l , m , s , t);
        if(m<t) ans+=query(rs , m+1 , r , s , t);
        return ans;
    }
    
    int main()
    {
       // freopen("a.in" , "r" , stdin);
        int n;
        while(~scanf("%d" , &n))
        {
            k=0;
            for(int i=0 ; i<n ; i++){
                scanf("%d%d" , &p[i] , &q[i]);
                a[k++]=p[i] , a[k++]=q[i];
            }
            sort(a , a+k);
            k = unique(a , a+k)-a;
            for(int i=0 ; i<n ; i++){
                int index = getIndex(p[i]);
                val[index] = p[i];
                p[i] = index;
                index = getIndex(q[i]);
                val[index] = q[i];
                q[i]=index;
            }
            for(int i=0 ; i<n ; i++) swap(val[p[i]] , val[q[i]]);
            ans = 0;
            memset(sum , 0 , sizeof(sum));
            for(int i=0 ; i<k ; i++){
                int index = getIndex(val[i]);
                ans += (ll)query(1 , 0 , k-1 , index+1 , k-1);
                update(1 , 0 , k-1 , index);
            }
            //判断当前第i个点和所有非离散化区间能形成的匹配
            for(int i=0 ; i<k ; i++){
                ans += (ll)abs(val[i]-val[getIndex(val[i])]) - (ll)abs(i-getIndex(val[i]));
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    可空类型转换为不可空的普通类型
    如何使用AspNetPager分页控件和ObjectDataSource控件进行分页
    TFS映射后丢失引用的问题
    (很好用)JS时间控件实现日期的多选
    取两个日期之间的非工作日的天数(指的是周六、周日)
    在日期格式化的时候提示错误:Tostring没有采用一个参数的重载
    Linq返回的集合类型不是已有的表格类型时的写法(谨记:列表的时候用)
    系统缓存全解析6:数据库缓存依赖
    实现文本框动态限制字数的实现(好方法)
    实现GridView内容循环滚动
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4470627.html
Copyright © 2020-2023  润新知