zoukankan      html  css  js  c++  java
  • Comet OJ

    A.险恶的迷宫

    题意:在二维平面坐标内,给出一个圆心坐标 (a,b),以及圆的半径 r , 再给出 n 个点的坐标 (x_i,y_i),  求有多少点在圆内。

    数据范围:0  <  n  <= 1e5,      0< r , x , y  <=1e9

    思路:对于判断距离根据勾股定理: sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) <= r ,即在圆的范围内。由于此题数据较大,sqrt可能导致精度损失,所以直接开long long 进行平方比较 :(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2 )<= r*r;

    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int maxn = 1e5+7;
    
    int main(){
        int n;
        ll a,b,r;
        cin>>n>>a>>b>>r;
        int ans = 0;
        for(int i=1;i<=n;i++){
            ll x,y;
            cin>>x>>y;
            if((x-a)*(x-a)+(y-b)*(y-b)<=r*r) ans++;
        }
        cout<<ans<<endl;
    }
    View Code

    B.夕日的光辉

    题意:给出长为 n 的字符串 str . 找到pink的子串序列.  求符合条件组成的pink自序列,相邻两个 ( 比如p与i互相相邻,n与k互相相邻 ) 最大坐标差-1
    思路:贪心:求p-i间隔最大时,i-n间隔最大时,n-k坐标间隔最大时.  比如要使p-i坐标差最大,即p取其能取道的最左边,i取其符合条件组成的最右边。

    code:

    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int maxn = 1e6+7;
    const int inf = 0x3f3f3f3f;
    int p0[maxn];
    int p1[maxn];
    int p2[maxn];
    int p3[maxn];
    
    int fismin(int com,int p[],int len){
    //找到第一个大于该数的位置
        for(int i=1;i<=len;i++){
            if(p[i]>com) return i;
        }
    //没找到返回0
        return 0;
    }
    int fismax(int com,int p[],int len){
    //找到最后一个小于该数的位置
        if(p[len]<com) return len;
        else{
            for(int i=1;i<=len;i++){
                if(p[i]>com) return i-1;
            }
            return len;
        }
    }
    int main(){
        int T;
        cin>>T;
        string s;
        while(T--){
            int len;
            cin>>len;
            cin>>s;
            int f0,f1,f2,f3;
            f0 = f1 = f2 = f3 = 0;
            //p-i间隔最大
            for(int i=0;i<len;i++){
                if(s[i]=='p') p0[++f0] = i;
                if(s[i]=='i') p1[++f1] = i;
                if(s[i]=='n') p2[++f2] = i;
                if(s[i]=='k') p3[++f3] = i;       
            }
            int ans = -1;
            if(f0&&f1&&f2&&f3){
                int ff1,ff2;
                //1.p0最左边,p3最右边,p2仅此p3右,p1仅此p2右 p0-p1
                ff2 = fismax(p3[f3],p2,f2);
                if(ff2){
                    ff1 = fismax(p2[ff2],p1,f1);
                    if(ff1) ans = max(ans,p1[ff1]-p0[1]);
                }
                //2.po最左边,p1仅次p0左,p3最有,p2仅存p3右 p1-p2
                ff1 = fismin(p0[1],p1,f1);
                ff2 = fismax(p3[f3],p2,f2);
                if(ff1&&ff2){
                    ans = max(ans,p2[ff2]-p1[ff1]);
                }
                //3.p0左,p1仅此左,p2仅此左,p3最右
                ff1 = fismin(p0[1],p1,f1);
                if(ff1){
                    ff2 = fismin(p1[ff1],p2,f2);
                    if(ff2) ans = max(ans,p3[f3]-p2[ff2]);
                }
    
                if(ans<0) cout<<-1<<endl;
                else cout<<ans-1<<endl;
            }else{
                cout<<-1<<endl;
            }
        }
    }
    View Code

    C.序列

    题意:初始长为 n 的 0 序列, 进行m次操作。每次操作给出区间 (l,r) ,将编号为奇数的序列 区间内的数字全部改成 第i次 操作的 i .同时在每一次操作前,把所有的序列复制一份。(如果还没理解题意,可以看下原题样例解析)

    求每次操作后的极大连续段的个数总和。

    思路:计数问题:由于是统计极大连续段(连续子区间)个数,所以我们可以 像dp计数一样,记录 以 x 位置结束(右端)的连续子区间个数 f [x]。比如初始时 长为 3的0序列,f[3] = 1;

    对于每次区间更改:我们可以知道 (l-1) 与l ,(r+1)与r的值肯定不一样,所以每次修改操作后 f[l-1] 与 f [r]的贡献值会增大,而增加的个数则是倍增的个数,即第i次操作时 2^(i-1)。

    对于没有修改的位置的贡献,由于每次倍增,所以统计个数时就将其乘以2.

    最后统计答案,就把所有位置的贡献相加即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2019;
    const ll mod=20050321;
    int n,m;
    ll f[maxn],p[maxn];
    //定义fx表示的序列中,存在极大连续段右端点为x的序列个数
    //x = n,a_x != a_x+1,
    //每一次不同的统计在于从1-n此时所有的值的贡献
    //由于每次对l,r操作后的值不同,又每次更新2^(i-1)个序列贡献,所以fr = fr + 2^(i-1);
    //由于1~i-1与r+1~n的部分元素没有改变,所以贡献翻倍
    int main()
    {
        cin>>n>>m;
        //预处理2^(i-1)
        p[0]=1;for(int i=1;i<=m;i++)p[i]=(p[i-1]*2)%mod;
        f[n]=1;
        for(int i=1;i<=m;i++)
        {
            int l,r;
            cin>>l>>r;
          
            for(int j=1;j<l-1;j++) f[j]=(f[j]*2)%mod;
            for(int j=r+1;j<=n;j++) f[j]=(f[j]*2)%mod;
    
            f[l-1]=(f[l-1]+p[i-1])%mod;
            f[r]=(f[r]+p[i-1])%mod;
            
            ll ans=0;
            for(int j=1;j<=n;j++) ans=(ans+f[j])%mod;
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    数据绑定表达式语法(Eval,Bind区别)
    使用博客园的第一件事 自定义主题
    sql2000 跨服务器复制表数据
    使用UpdatePanel 局部刷新出现中文乱码的解决方法!!
    MMC不能打开文件MSC文件
    sql 日期 、时间相关
    loaded AS2 swf call function in AS3 holder
    Rewrite the master page form action attribute in asp.net 2.0
    100万个不重复的8位的随机数
    flash 中实现斜切变型
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11827843.html
Copyright © 2011-2022 走看看