罪犯轉移

題目描述

C市現在要轉移一批罪犯到D市,C市有n名罪犯,按照入獄時間有順序,另外每個罪犯有一個罪行值,值越大罪越重。現在爲了方便管理,市長決定轉移入獄時間連續的c名犯人,同時要求轉移犯人的罪行值之和不超過t,問有多少種選擇的方式? 

輸入描述:
第一行數據三個整數:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入獄時間給出每個犯人的罪行值ai(0≤ai≤1e9)
輸出描述:
一行輸出答案。
輸入例子:
3 100 2
1 2 3
輸出例子:2

思路:其實題目講得很複雜,但要做的事情很簡單,就是連續c個罪犯的罪犯值相加不超過t。比如有5人,連續3人,這裏的組合就只有1 2 3 、2 3 4 、 3 4 5這幾種。所以寫循環,測相加值就可以了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int plus(int *in,int start,int end)
    {
    int sum=0;
    for(int i=start;i<end;i++)
        sum = sum+in[i];
    return sum;
    
}


int main()
    {
    int n=0,t=0,c=0;
    int wayscount=0;
    int *crime;
    while(scanf("%d%d%d",&n,&t,&c) != EOF)
        {
        if(c<=n)
            {
                wayscount=0;
                sum=0;
        	crime = (int *)malloc(sizeof(int)*n);
        	for(int i=0;i<n;i++)
            	scanf("%d",&crime[i]);
            
            int start = 0;
            while(start+c<=n)
                {
                if(plus(crime,start,start+c)<t)
                    start++;
                    wayscount++;
            }
            printf("%d\n",wayscount);
            free(crime);
        }
    }
    
    return 0;
}



這是我一開始的代碼,結果是運行時間過長,無法編譯通過。這就很尷尬了。我這裏都沒有很大量的循環。
然後我就去參考別人的代碼。發現問題出在,我每次都在將c個罪犯值重新加一次,所以在數據量大的時候浪費了很多時間。
這裏參考了別人的思路,感覺很有用,就記下來。
這裏類似一個滑塊窗口。

這樣一來累加就只做一次,大大縮減了運行時間。我這裏爲了方便,就沒有將累加函數寫回main裏了。如果對時間要求很高,建議全寫在main裏,畢竟函數跳轉,變量壓棧,出棧這些也都是需要時間的。貼上改進後的代碼
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int plus(int *in,int start,int end)
    {
    int sum=0;
    for(int i=start;i<end;i++)
        sum = sum+in[i];
    return sum;
    
}


int main()
    {
    int n=0,t=0,c=0;
    int wayscount=0;
    int *crime;
    int sum=0;
    while(scanf("%d%d%d",&n,&t,&c) != EOF)
        {
        if(c<=n)
            {
            wayscount = 0;
            sum = 0;
        	crime = (int *)malloc(sizeof(int)*n);
        	for(int i=0;i<n;i++)
            	scanf("%d",&crime[i]);
            
            int start = 0;
            sum = plus(crime,start,start+c);
            if(sum<=t)
                wayscount++;
            for(int j=c;j<n;j++)
                {
                sum=sum-crime[j-c];
                sum=sum+crime[j];
                if(sum<=t) wayscount++;
            }
            
            printf("%d\n",wayscount);
            free(crime);
        }
    }
    
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章