1. 程式人生 > >noip2013普及組解題報告

noip2013普及組解題報告

第一題:記數問題

題目描述 Description

試計算在區間1到n的所有整數中,數字x(0≤x≤9)共出現了多少次?例如,在1到11中,即在1、2、3、4、5、6、7、8、9、10、11中,數字1出現了4次。

輸入描述 Input Description

輸入共1行,包含2個整數n、x,之間用一個空格隔開。

輸出描述 Output Description

輸出共1行,包含一個整數,表示x出現的次數。

樣例輸入 Sample Input

11 1

樣例輸出 Sample Output

4

這題與往年的題目有點相似,資料範圍也才1——1000000,不大,所以可以直接做:

#include <iostream>
using namespace std;
int x,r,l,k,ans;
int main(){
    cin>>r>>x;
    for(l=1;l<=r;l++)
    {
        k=l;
        while(k!=0){if(k%10==x)ans++;k/=10;}
    }
    cout<<ans;
    return 0;
}

第二題:表示式求值

題目描述 Description

給定一個只包含加法和乘法的算術表示式,請你程式設計計算表示式的值。

輸入描述 Input Description

輸入僅有一行,為需要你計算的表示式,表示式中只包含數字、加法運算子“+”和乘法運算子“*”,且沒有括號,所有參與運算的數字均為0到2^31-1之間的整數。輸入資料保證這一行只有0~9、+、*這12種字元。

輸出描述 Output Description

輸出只有一行,包含一個整數,表示這個表示式的值。注意:當答案長度多於4位時,請只輸出最後4位,前導0不輸出。

樣例輸入 Sample Input

[Sample 1]
1+1*3+4
[Sample 2]
1+1234567890*1
[Sample 3]
1+1000000003*1

樣例輸出 Sample Output

[Sample 1]
8
[Sample 2]
7891
[Sample 3]
4


其實題目本意非常簡單,就是給個表示式,我的思路是:

1)讀入一個數字讀入一個符號(因為題目讓我們只保留後四位,所以讀入數字時,要mod 10000)

2)根據優先順序,先處理乘號

3)直接累加

code:

#include<iostream>
using namespace std;
unsigned long long num[100000];
char sign[100000];
unsigned long long i,l=1,ans;
int main(){
    cin>>num[1];
    while(cin>>sign[l]){
        l++;
        cin>>num[l];
        num[l]%=10000;
    }
    l--;
    for(i=1;i<=l;i++)
    if(sign[i]=='*')
    {num[i+1]=num[i]*num[i+1];num[i]=0;num[i+1]%=10000;}
    for(i=1;i<=l+1;i++)ans+=num[i];
    cout<<ans%10000;
    return 0;
}
	

第三題:小朋友的數字

題目描述 Description

有n個小朋友排成一列。每個小朋友手上都有一個數字,這個數字可正可負。規定每個小朋友的特徵值等於排在他前面(包括他本人)的小朋友中連續若干個(最少有一個)小朋友手上的數字之和的最大值。
作為這些小朋友的老師,你需要給每個小朋友一個分數,分數是這樣規定的:第一個小朋友的分數是他的特徵值,其它小朋友的分數為排在他前面的所有小朋友中(不包括他本人),小朋友分數加上其特徵值的最大值。
請計算所有小朋友分數的最大值,輸出時保持最大值的符號,將其絕對值對p取模後輸出。

輸入描述 Input Description

第一行包含兩個正整數n、p,之間用一個空格隔開。
第二行包含n個數,每兩個整數之間用一個空格隔開,表示每個小朋友手上的數字。

輸出描述 Output Description

輸出只有一行,包含一個整數,表示最大分數對p取模的結果。

樣例輸入 Sample Input

[Sample 1]
5 997
1 2 3 4 5
[Sample 2]
5 7
-1 -1 -1 -1 -1

樣例輸出 Sample Output

[Sample 1]
21
[Sample 2]
-1

資料範圍及提示 Data Size & Hint

【樣例說明】
樣例1小朋友的特徵值分別為1、3、6、10、15,分數分別為1、2、5、11、21,最大值21對997的模是21。
樣例2小朋友的特徵值分別為-1、-1、-1、-1、-1,分數分別為-1、-2、-2、-2、-2,最大值-1對7的模為-1,輸出-1。

【資料範圍】
對於50%的資料,1≤n≤1,000,1≤p≤1,000所有數字的絕對值不超過1000;
對於100%的資料,1≤n≤1,000,000,1≤p≤10^9,其他數字的絕對值均不超過10^9。


比較easy的一個DP,特殊值就用最大子段和來求,分數不能直接求,要找規律,要麼越來越大,要麼越來越小,越來越小輸出第一個,越來越大輸出第n個

時間複雜度O(2n)

code:

#include<cstdio>

#include<cstring>

#include<cstdlib>

#define LL long long// 因為這道題有可能會很大的數,用longlong

using namespace std;

LL maxx ( LL x, LL y){ return x > y ? x : y; } // 求兩個數的最大值

LL n, p, a[1100000];// a是一開始的那一段數

LL b[1100000],c[1100000]; // b是特徵值,c是分數

int main (){

    int i, j;

    scanf ( "%lld%lld", &n,&p );

    for ( i = 1; i <= n; i ++ )

     scanf( "%lld", &a[i] );

    b[1] = a[1];

    LL now = maxx ( a[1], 0 ); // 看看第一個數是正數還是負數,如果是負數,則忽略這一個數,免得使統計的數變小

    for ( i = 2; i <= n; i ++ ){

        b[i]= b[i - 1]; // 先等於前面的特徵值

        now+= a[i]; // 把這個累加值加上當前小孩子手上的數字

        b[i] = maxx ( now, b[i] ); // 看看是前面特徵值的大還是累加值大

        if( now < 0 ) now = 0; // 如果累加值比0小,那又把它變成0,重新累加

    }

    c[1] = b[1];

    c[2] = c[1] + b[1]; // c1和c2是固定的,可以現在前面算

    int ok = 0; // ok就是看是最後的值更大些還是第一個更大些

    LL tmp = c[1];

    for ( i = 2; i < n; i ++ ){

        tmp += maxx ( b[i], 0ll );

        if ( tmp >= 0 ){ // 如果這個累加值比0大,那麼就證明會累加越來越大

            ok = 1;

            break;

        }

    }

    for ( i = 3; i <= n; i ++ )

     c[i]= ( c[i - 1] + maxx ( b[i - 1], 0ll ) ) % p; // 求每個人分數的最大值

    if ( ok ) // 如果最後的大些

     printf ( "%d\n", int ( c[n] ) ); // 輸出最後的

    else // 如果第一個大些

     printf ( "%d\n", int ( c[1] % p ) );// 輸出第一個

    return 0;  

}
		

第四題:車站分級

題目描述 Description

一條單向的鐵路線上,依次有編號為1, 2, …, n的n個火車站。每個火車站都有一個級別,最低為1級。現有若干趟車次在這條線路上行駛,每一趟都滿足如下要求:如果這趟車次停靠了火車站x,則始發站、終點站之間所有級別大於等於火車站x的都必須停靠。(注意:起始站和終點站自然也算作事先已知需要停靠的站點)
例如,下表是5趟車次的執行情況。其中,前4趟車次均滿足要求,而第5趟車次由於停靠了3號火車站(2級)卻未停靠途經的6號火車站(亦為2級)而不滿足要求。

現有m趟車次的執行情況(全部滿足要求),試推算這n個火車站至少分為幾個不同的級別。

輸入描述 Input Description

第一行包含2個正整數n, m,用一個空格隔開。
第i+1行(1≤i≤m)中,首先是一個正整數s_i(2≤s_i≤n),表示第i趟車次有s_i個停靠站;接下來有s_i個正整數,表示所有停靠站的編號,從小到大排列。每兩個數之間用一個空格隔開。輸入保證所有的車次都滿足要求。

輸出描述 Output Description

輸出只有一行,包含一個正整數,即n個火車站最少劃分的級別數。

樣例輸入 Sample Input

[Sample 1]
9 2
4 1 3 5 6
3 3 5 6
[Sample 2]
9 3
4 1 3 5 6
3 3 5 6
3 1 5 9

樣例輸出 Sample Output

[Sample 1]
2
[Sample 2]

3

拓撲排序模板,只要在拓撲排序的過程中找到不能刪除的,需要的層次就++

相比較往年是為數不多的100行以內的題目了

#include<stdio.h>
#include<iostream>
#include<vector>
#include<memory.h>
using namespace std;
const int MAX_N = 2002;
int N,M;int P;
int s[MAX_N]; //how many stations in route i
int level[MAX_N]; //level
int infor[MAX_N][MAX_N]; //info about route i
vector<int> d[MAX_N]; //don't stop here
vector<int> p[MAX_N]; //stop here
int adj[MAX_N][MAX_N];
int con[MAX_N];
void init()
{
	int i,j,k;
	scanf("%d %d",&N,&M);
	memset(adj,-1,sizeof(adj));
	P=N;
	for (i=1;i<=M;i++)
	{
		scanf("%d",&s[i]); //讀入 
		for (j=1;j<=s[i];j++)
		scanf("%d",&infor[i][j]);
		if (infor[i][s[i]]-infor[i][1]+1==s[i]) continue; 
		//如果在這條線路當中最後一個車站-第一個車站序號+1=總的經過車站數量,也就沒有不停的車站,就不存在做的可能
		//而題目保證一條線路中至少有2個停的車站,所以放心 
		for (j=infor[i][1],k=1;j<=infor[i][s[i]];j++)
		{
			if (j==infor[i][k]) {p[i].push_back(j);k++;}
			else {d[i].push_back(j);} //掃描那些節點在d停車的節點中 那些在p不停的當中 
		} 
		P++; //產生bt節點 
		for (j=0;j<d[i].size();j++)
		adj[d[i][j]][P]=0,con[P]++; //構造(Dij,P)有向邊 con[P]入度++ 
		for (j=0;j<p[i].size();j++)
		adj[P][p[i][j]]=1,con[p[i][j]]++;
	}
	for (i=1;i<=P;i++)
	level[i]=1;//初始化 level至少為1 
}
int find_zero()
{
	int i;
	for (i=1;i<=P;i++)
	if (con[i]==0) return i; //尋找入度為0的節點 
	return -1;
}
void work()
{
	int i,j,k;
	for (i=1;i<=P;i++)
	{
		k=find_zero();
		if (k==-1) return ; //如果沒有入度為0的頂點 說明做完了 
		for (k<=N?j=N+1:j=1;k<=N?j<=P:j<=N;j++)
		//完全可以寫for (j=1;j<=P;j++)
		//不過這是常數級別優化
		//因為根據題意可知
		//如果存在邊 (x,y) 則x∈車站T集合 y∈bt節點集合
		//否則 y∈車站T集合 x∈bt節點集合
		if (adj[k][j]!=-1) //-1表示沒有變 
		{
			level[j]=max(level[j],level[k]+adj[k][j]); //求最長路 
			adj[k][j]=false; //刪除這條邊 
			con[j]--;  //入度-- 
		}
		con[k]=-1; //標記已經做過這個頂點 
	}
}
void put()
{
	int i;
	int ans = 0;
	for (i=1;i<=P;i++)
	ans  = max(ans,level[i]); //尋找最大等級 
	printf("%d",ans);
}
int main()
{
	init();
	work();
	put();
	return 0;
}


相關推薦

noip2013普及解題報告

第一題:記數問題 題目描述 Description 試計算在區間1到n的所有整數中,數字x(0≤x≤9)共出現了多少次?例如,在1到11中,即在1、2、3、4、5、6、7、8、9、10、11中,數字1出現了4次。 輸入描述 Input Descriptio

NOIP2000普及解題報告

opened close clas tdi char using div || src /霧 noip2000發生了什麽?為什麽洛谷上就一道題- - 計算器的改良 分析:字符串模擬題。記錄分別記錄等式兩邊的系數與常數即可。以前在codevs上做過,也就直接把代碼貼上來了。

NOIP1999普及解題報告

分析 eat 報告 nlogn cnblogs clas () fun turn 不知怎麽地,洛谷的noip1999普及組的題和以前考的不一樣 /霧 回文數 分析:一道高精度加法的模擬題,註意還有16進制。 #include<iostream> #inclu

NOIP2002普及解題報告

ostream 答案 class ret opened none fin nbsp b- 過河卒 分析:簡單遞推題。註意答案要longlong #include<iostream> #include<algorithm> using namesp

NOIP 2018 普及 解題報告

今年的題目出的有點詭異,難度跨越有點大 入門  to 普及- to(注意:前方東非大裂谷,請小心慢行) 提高+/省選- to 提高+/省選- 不過實際上沒有這麼難 T3、T4 一個DP 一個暴力(雖然不是正解) 也就可以過了 扯入正題 T1 標題統計 這道題十分的水,

NOIP2018普及解題報告

解題報告 洛谷 5015 標題統計 程式碼(題目過水) 洛谷 5016 龍虎鬥 分析 程式碼 洛谷 5017 擺渡車 分析(線性dp) 程式碼(線性dp) 分析(斜率

NOIP 2010 普及解題報告

NOIP 2010普及組解題報告 北京市八一中學 王祺磊 感謝: 我也學習一下,現在的流行趨勢,先開始感謝,但這真的是發自內心的感覺,讓我發出一下這些感謝。 一、感謝和我一起並肩戰鬥資訊學奧賽教學一線的老師們,是你們給了我溫暖,讓我感受到一個溫馨的集體,在其中,我們一起學習,一起研討

NOIP2014普及解題報告 -----by IAMACER

本人是濰坊一中的wyw,69級,今年高一, 現在馬上就要NOIP了, 打算把歷年的NOIP普及、提高組題目都做一下, 然後寫寫解題報告∵這個報告主要是給初中同學看的,所以我會寫的詳細一點 NOIP2014普及組解題報告 Prolem 1 珠心算測

NOIP2017普及 解題報告

前言 好吧,由於賽時本人還是一個蒟蒻,(雖然現在也是),導致一直沒有做完後面兩題。。。 先說下賽時分數吧。。。 前兩題日常水過,後兩題日常放棄,其實第三題有想著做但是沒時間了 第一題 第二題 第三題 第四題 Accepte

紀中訓練 day5 【NOIP普及】模擬賽D 解題報告

目錄 大意 從左到右,問加了一個’p’後一共有幾個noi?(p可以為n,o,i中的一個)長度小於100001 思路 加p之前,noi的個數為每個o之前n的個數*之後i的個數並累加。 加p之後,有三種情況:N,O,I N肯定是放在

洛谷 P1982 小朋友的數字(NOIp2013普及T3)

文件 ret vijos 觀察 個數 color 符號 朋友 麻煩 題目描述 有 n 個小朋友排成一列。每個小朋友手上都有一個數字,這個數字可正可負。規定每個小朋友的特征值等於排在他前面(包括他本人)的小朋友中連續若幹個(最少有一個)小朋友手上的數字之和的最大值。 作為這些

表達式求值(NOIP2013 普及第二題)

tool ber 算術表達式 class 整數 括號 給定 編程 解釋 描述 給定一個只包含加法和乘法的算術表達式,請你編程計算表達式的值。 格式 輸入格式 輸入僅有一行,為需要你計算的表達式,表達式中只包含數字、加法運算符“+”和乘法運算符“*”,且沒有括號,所有參與運算

[jzoj]2018.08.09【NOIP提高】模擬賽C:解題報告

目錄: 1.種類分配(Breed Assignment) 2.資訊傳遞(Message Relay) 3.計算周長(Perimeter) 4.找奶牛(Find the Cow!) 1.種類分配(Breed Assignment) 題目:

2018年12月29日普級 解題報告

首先看第一題,比較明顯的模擬題,打了高精度,第二題暫時沒思路,先剛第三題,先想到dfsdfsdfs求層數,發現可以直接用並查集搞搞,就過了,第四題沒思路,就碼了第四題,發現可以直接用桶排,過掉。第四題仔

2018年11月30日普級 解題報告

首先第一題是個很明顯的水題切掉了,第二題發現都是1,於是就輸出了1,竟然有50!第三題打了貪心40,總分190 T1 婚禮上的小杉 排序題,略掉吧。。。 話說我是本題唯一一個O(n)O(n)O(n)過的 T2 玩詐欺的小杉 給定變化規則,求最終矩陣 這是經典

NOIP2013普及 題解

T1  計數問題 題目描述 試計算在區間 1 到 n 的所有整數中,數字 x(0 ≤ x ≤ 9)共出現了多少次?例如,在 1 到 11 中,即在 1、2、3、4、5、6、7、8、9、10、11 中,數字 1 出現了 4 次。 輸入輸出格式 輸入格式:輸入檔名為 count

NOIP2013普及P2】表示式求值(NKOJ2500)題解

【NOIP2013普及組P2】表示式求值 Time Limit:10000MS  Memory Limit:128000K Total Submit:37 Accepted:19 Case Time

【蒻爆了的NOIP系列--普及複賽】(4)NOIP2013普及複賽題解

這只是一個作業,如果有幫到您的,我只能說。。。這不科學。。。 ————————————華麗的分割線———————————— 第一題: 神似noip2016t1… 貌似就資料範圍和輸入方式

luogu1981 表示式求值(NOIP2013普及第2題)

時空限制    1000ms/128MB 題目描述 給定一個只包含加法和乘法的算術表示式,請你程式設計計算表示式的值。 輸入輸出格式 輸入格式: 一行,為需要你計算的表示式,表示式中只包含數字、加法運算子“+”和乘法運算子“×”,且沒有括號,所有參與運算的數字均

NOIP2013普及 T2 表示式求值

OJ地址:洛谷P1981 CODEVS 3292 正常寫法是用棧 1 #include<iostream> 2 #include<algorithm> 3 #inclu