1. 程式人生 > 實用技巧 >關於線性篩的一些思考

關於線性篩的一些思考

題意,給你一個非遞減的陣列,問你裡面有沒有不能構成三角形的邊,如果存在則輸出,否則輸出-1;

思路:非遞減,說明剛開始兩個加一塊是最小的,如果後面存在比他們的和大的就肯定有三條邊構不成三角形了,如果後面的比他們的和都要小,說明這個數組裡面任意三條邊都能構成三角形。

#include<bits/stdc++.h>
#include<map>
const int N=5e4+10;
using namespace  std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int
n; cin>>n; long long a[N]; for(int i=0; i<n; i++) cin>>a[i]; long long ans=a[0]+a[1]; int fla=0; int lo=0; for(int i=2; i<n; i++) { if(ans<=a[i]) { fla=1; lo
=i; break; } } if(fla==1) cout<<"1"<<" "<<"2"<<" "<<lo+1<<endl; else cout<<"-1"<<endl; } return 0; }
View Code

題意:兩個人玩遊戲,每次去掉一串1,每次得分是每次去掉的串中1的個數,問先手最多能獲得的多少分。

思路:統計一下每個都是1的串裡面含有1的個數,然後壓入優先佇列,(剛開始用的sort排序T掉了...)然後在從佇列中取出來,在隔一次加一次就行了。

#include<bits/stdc++.h>
#include<map>
#include<queue>
const int N=100000+10;
using namespace  std;
int main()
{
    int t;
    cin>>t;
    priority_queue<int> q;
    while(t--){
        string s;
        cin>>s;
        int ans=0;
        int j;
        for( j=0; j<s.size(); j++){
            if(s[j]=='0')
                continue;
            else
                break;
        }
        for(int i=j; i<s.size(); i++)
        {
            if(s[i]=='0'){
                q.push(ans);
                ans=0;
            }
            else if(s[i]=='1'){
                ans++;
            }

        }
        if(ans!=0)
            q.push(ans);
        int sum=0;
        int flage=1;
        while(!q.empty()){
            int s=q.top();
            q.pop();
            if(flage%2==1)
            sum+=s;
            flage++;
        }
        cout<<sum<<endl;
    }
    return 0;
}
View Code

題意:有一個數組,陣列中每個元素只包含0-9這10中數字。問有多少個子陣列滿足子陣列和等於該子陣列長度。

思路:把公式變形一下:假設 i = 4 , j = 6.那麼就是要找a[4]+a[5]+a[6]=6 - 4 +1 = 3;

然後我讓a[4]-1+a[5]-1+a[6]-1=3-3=0;

所以我讓每個數減1,就是問那些區間的和是0.也就是

區間和為0有兩種情況

1.如果sum [ i ]==0,就說明存在一個ans++;

2.如果sum[ i ]= =sum[ j ],這時候就要統計一下sum[ i ]出現的次數,就得出規律。如果一個數出現的次數是t,那麼區間為0的個數是

t=t-1;
ans+=t*(1+t)/2;

0的時候單獨計算一下就行了

ans+=t*(1+t)/2;  //t不用減1了
 
#include<bits/stdc++.h>
#include<map>
#include<queue>
using namespace  std;
typedef long long ll;
const int N=1e5+10;
int main()
{
    int t;
    cin>>t;
    map<ll,ll>q;
    queue<ll>p;
    while(t--){
        int sum[N],n,a[N];
        string s;
        q.clear();
        cin>>n;
        cin>>s;
        for(int i=0; i<n; i++){
            a[i]=s[i]-'0'-1;
        }
        sum[0]=a[0];
        p.push(sum[0]);
        q[sum[0]]++;
        for(int i=1; i<n; i++){
            sum[i]=sum[i-1]+a[i];
            if(q[sum[i]]==0){
                p.push(sum[i]);
            }
            q[sum[i]]++;
        }
        ll k=q[0];
        ll ans=k*(1+k)/2;
        while(!p.empty()){

            ll s=p.front();
            if(s==0){
                p.pop();
                continue;
            }
            s=q[s];
            s=s-1;
            ans+=s*(1+s)/2;
            p.pop();
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code