程式設計思維與實踐 CSP M1

2021-10-04 04:35:02 字數 4012 閱讀 9027

咕咕東是個貪玩的孩子,有一天,他從上古遺跡中得到了乙個神奇的圓環。這個圓環由字母表組成首尾相接的環,環上有乙個指標,最初指向字母a。咕咕東每次可以順時針或者逆時針旋轉一格。例如,a順時針旋轉到z,逆時針旋轉到b。咕咕東手裡有乙個字串,但是他太笨了,所以他來請求你的幫助,問最少需要轉多少次。

輸入只有一行,是乙個字串。

輸出最少要轉的次數。

zeus

資料點 字串長度

1,2 小於等於10

3,4,5 小於等於100

6,7,8,9,10 小於等於10000

要使總的轉動次數最少,就必須使每一次轉動的次數最少。每一次在圓環上轉動無非就是順時針或逆時針轉動,基本思路為選取每次順時針或逆時針轉動的最少次數即可。

相鄰的兩個字元的轉動距離(不一定是最短距離)可以通過ascii碼直接相減

order=str[i+1]

-str[i]

; order=order>=

0?order:

(-order)

;

圓環上兩個字元的最小距離不超過13(否則可以從相反方向轉動,距離為26-order),因此直接可以取這兩個值的最小值,最後累加即可。

order=order>13?

(26-order)

:order;

當然不要忘了一開始是從a開始轉動的,把a放在字串陣列的開頭即可

#include

"iostream"

#include

"stdio.h"

#include

"string.h"

using

namespace std;

char str[

10005];

intmain()

cout

}

咕咕東考試周開始了,考試周一共有n天。他不想考試周這麼累,於是打算每天都吃頓好的。他決定每天都吃生煎,咕咕東每天需要買ai個生煎。但是生煎店為了刺激消費,只有兩種購買方式:①在某一天一次性買兩個生煎。②今天買乙個生煎,同時為明天買乙個生煎,店家會給乙個券,第二天用券來拿。沒有其餘的購買方式,這兩種購買方式可以用無數次,但是咕咕東是個節儉的好孩子,他訓練結束就走了,不允許訓練結束時手裡有券。咕咕東非常有錢,你不需要擔心咕咕東沒錢,但是咕咕東太笨了,他想問你他能否在考試周每天都能恰好買ai​個生煎。

其中(1 <= n <= 100000)

(1 <= ai

<= 10000)

41 2 1 2

對於ai,分析兩種購買方式:

1、一次性買兩個,不會改變ai的奇偶性,

2、今天乙個明天乙個,會同時改變ai,ai+1的奇偶性

若ai是偶數,直接選擇方案一

若ai是奇數,就必須至少選擇一次方案二,會同時改變ai,ai+1的奇偶性,奇變偶,偶變奇

可以看出,如果輸入的陣列能滿足條件,那麼通過兩種購買方式後,最後一天ai通過購買後一定會是偶數

那麼通過奇偶變換模擬購買

scanf

("%d"

,&temp)

; temp+

=flag;

if(temp &

1) flag=1;

//temp是奇數

else flag=

0;

判斷最後乙個數的奇偶性即可

if

(temp &1)

printf

("no");

else

printf

("yes"

);

#include

#include

intmain()

if(temp &1)

printf

("no");

else

printf

("yes");

printf

("\n");

}

宇宙射線會在無限的二維平面上傳播(可以看做乙個二維網格圖),初始方向預設向上。宇宙射線會在發射出一段距離後**,向該方向的左右45°方向**出兩條宇宙射線,同時威力不變。宇宙射線會**n次,每次**後會在**方向前進ai 個單位長度。計算出共有多少個位置會被打擊。

輸入第一行包含乙個正整數n(n <= 30),表示宇宙射線會**n次,第二行包含n個正整數a1,a2…an,第i個數ai(ai

<= 5)表示第i次**的宇宙射線會在它原方向上繼續走多少個單位長度。

輸出乙個數ans,表示有多少個位置會被降智打擊。

442

23

39
10% <=10

40% <=20

100% <=30

首先需要認識到這是乙個指數複雜度的問題(一變二,二變四,……),形成類似樹狀結構的圖形,考慮bfs或dfs進行路徑探索,這裡使用dfs。

dfs當時要使用遞迴,遞迴函式裡要做什麼呢?從乙個點開始,朝著乙個方向前進一段距離,這是遞迴函式內部的基本內容。然後到終點後,分開為兩個方向再進行遞迴,每個遞迴函式內進行兩次遞迴呼叫,這就是遞迴函式內的基本內容。

這裡使用兩個陣列表示線段前進的方向,可以理解為是8個點(x,y)的結構體陣列,是向該方向前進的單位長度,向該方向前進乙個單位就將點進行累加。

遞迴函式中還需要引數是當前遞迴的層數cur(分叉了幾次)和最多遞迴的層數times,通過這兩個引數判斷函式的返回。

點(x,y)向direc方向前進a[cur],用二維陣列flag記錄點的到達情況,以便計數線段覆蓋點的數目ans

for

(int i=

1;i<=a[cur]

;i++

)

到達終點後進行**

dfs

(x,y,cur+1,

(direc+7)

%8,times)

;//逆時針旋轉45度方向

dfs(x,y,cur+1,

(direc+1)

%8,times)

;//順時針旋轉45度方向

但是由於複雜度是指數級別的,這樣的dfs很容易超時,需要進行剪枝。點(x,y)在direc方向前進了a[cur],如果還有乙個點(x,y也是相同的情況,那麼就沒有必要繼續進行遞迴了。

if

(cur>times || vis[x]

[y][cur]

[direc]

)return

; vis[x]

[y][cur]

[direc]

=true

;

#include

#include

#include

using

namespace std;

int dx=

;int dy=

;bool flag[

600]

[600]=

;bool vis[

600]

[600][

31][8

]=;int a[31]

;int ans=0;

void

dfs(

int x,

int y,

int cur,

int direc,

int times)

}dfs

(x,y,cur+1,

(direc+7)

%8,times)

;dfs

(x,y,cur+1,

(direc+1)

%8,times);}

intmain()

dfs(

300,

300,1,

0,n)

;printf

("%d"

,ans)

;return0;

}

程式設計思維與實踐 CSP M1

我瘋了 為什麼這麼多篇部落格只有這篇說題目重複率較高 部落格管理裡就這篇前面有個驚嘆號逼死強迫症啊啊啊 題目 輸出 最少需要轉的次數 思路 取模 就是乙個取模的問題。每一次轉的時候,都是兩個字元之間的比較。除第乙個字元是與 a 比較以外,其他的字元都是與後乙個字元進行比較。因此用for迴圈實現累加,...

程式設計思維與實踐 CSP M1 補題

a 咕咕東的奇遇 題意咕咕東是個貪玩的孩子,有一天,他從上古遺跡中得到了乙個神奇的圓環。這個圓環由字母表組成首尾相接的環,環上有乙個指標,最初指向字母a。咕咕東每次可以順時針或者逆時針旋轉一格。例如,a順時針旋轉到z,逆時針旋轉到b。咕咕東手裡有乙個字串,但是他太笨了,所以他來請求你的幫助,問最少需...

程式設計思維與實踐 CSP M1補題

題目描述 咕咕東是個貪玩的孩子,有一天,他從上古遺跡中得到了乙個神奇的圓環。這個圓環由字母表組成首尾相接的環,環上有乙個指標,最初指向字母a。咕咕東每次可以順時針或者逆時針旋轉一格。例如,a順時針旋轉到z,逆時針旋轉到b。咕咕東手裡有乙個字串,但是他太笨了,所以他來請求你的幫助,問最少需要轉多少次。...