10.2 廣州集訓 Day1
阿新 • • 發佈:2017-10-02
char 個數 包括 log 相同 name noi continue 格式
平衡(balance,1s,128M)
【題目描述】 P同學總共有k根火柴,分別放在擺成一列的n個火柴盒內,保證k是n的倍數。P同學想要每個火柴盒都有相同數目的火柴,每次他可以從一個火柴盒中拿一根火柴放到相鄰的火柴盒中。他想知道他最少要移動多少次。 【輸入格式】 從balance.in中讀入。 第一行一個整數n,表示火柴盒數。 第二行n個整數,表示第i個火柴盒內有根火柴。 【輸出格式】 輸出到balance.out中。 一行一個整數,表示最少要移動多少次。 【樣例一輸入】 6 1 6 2 5 3 7 【樣例一輸出】 12 【子任務】 30%數據,1≤n≤100,0≤????≤100 100%數據,1≤n≤50000,0≤????≤10^9
Solution:
模擬+貪心。
沒有什麽其他的特別的東西,類似於NOIP2002的紙牌。
我們可以先算出各盒火柴之和的sum,由p=sum/n可以得到每盒火柴的個數。
然後從1到n尋找,如果火柴數大於0,就把多出的火柴移到下一個火柴盒。
反之,如果小於0,就把下一個火柴盒的火柴移到這個火柴盒。
值得一提的是,即使火柴變成負數也可以實現,因為我們可以保證存在一種合適的移動方法恒為非負。
1 #include<cstdio>
2 #define MAXN 50005
3 #define LL long long
4 using namespace std;
5 int n,p=0;LL sum=0,cnt=0;
6 LL a[MAXN];
7 inline LL read(){
8 int x=0,f=1;char ch=getchar();
9 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
10 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
11 return x*f;
12 }
13 LL Abs(LL x){return x>0?x:-x;}
14 int main(){
15 freopen("balance.in","r",stdin);
16 freopen("balance.out","w",stdout);
17 n=read();
18 for(int i=1;i<=n;i++) a[i]=read(),sum+=a[i];
19 p=sum/n;
20 for(int i=1;i<=n;i++) a[i]-=p;
21 //for(int i=1;i<=n;i++) printf("a[i]=%d\n",a[i]);
22 for(int i=1;i<=n;i++) {
23 if(!a[i]) continue;
24 else if(a[i]<0) cnt-=a[i];
25 else if(a[i]>0) cnt+=a[i];
26 a[i+1]+=a[i];
27 }
28 printf("%lld",Abs(cnt));
29 return 0;
30 }
道路(road,3s,512M)
我們看見了一個由m行n列的1*1的格子組成的矩陣,每個格子(I,j)有對應的高度h[i][j]和初始的一個非負權值v[i][j].我們可以隨便選擇一個格子作為起點,然後在接下來的每一步當中,我們能且只能到達與當前格子有邊相鄰的四個格子中的高度不超過當前格子高度的格子,每當我們到達一個新格子(包括一開始選擇的初始格子),我們就能得到該格子的權值分,然後該格子的權值就會等概率變成不比當前的權值大的一個非負權值。每一個格子在滿足前面條件情況下,可以走任意多次。
我們希望得到一個最大的期望權值和路徑,並給出這個最大的期望權值和。
輸入格式:
第一行兩個正整數表示m,n。
接下來的m行,每行n個正整數,表示h[i][j].
接下來的m行,每行n個非負整數,表示v[i][j].
輸出格式:
一行一個實數,表示所求的最大期望權值和。保留零位小數。
輸入樣例:
1 3
1 2 1
1 2 3
輸出樣例:
5
數據範圍:
對於30%的數據,保證n,m不超過100.
對於另外20%的數據,保證不存在相同的高度的格子。
對於100%的數據,保證n,m不超過1000.所有權值與高度不超過10^9.
Solution:
留坑。下課填。
10.2 廣州集訓 Day1