3.25考试
WG一言不合又考試了。。。
題目不難
考得很萎
不知考啥
額
1、簡單的數列
Description
一個簡單的數列問題:?
給定一個長度為n的數列,求這樣的三個元素 ai,aj,ak 的個數,滿足 ai<aj>ak,且 i<j<k 。
Input
第1行是一個整數n(1<=n<=50000)。?
接下來n行,每行一個元素ai(0<=ai<=32767)。
Output
一個數,滿足 ai<aj>ak (i<j<k) 的個數。
Sample Input
5?
1?
2?
3?
4?
1
Sample Output
6
Hint
數據范圍:?
對于30%的輸入數據有n<=200。?
對于80%的輸入數據有n<=10000。?
對于100%的輸入數據有n<=50000。
樹狀數組記錄每個數左邊有幾個數比它小,右邊有幾個數比他小,相乘,再全部相加就是答案,應該很好證吧
#include<cstdio> #include<algorithm> #include<cstring> #define lb(o) ((o)&(-(o))) #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; int T[32800],L[50002],R[50002]; int num[50002]; int n; inline void update(int r){while(r<=32768)++T[r],r+=lb(r); } inline int sum(int r){int ans=0;while(r)ans+=T[r],r-=lb(r);return ans; } inline int gi(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0')f=(ch=='-')?-1:f,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*f; } int main(){n=gi();for(int i=1;i<=n;i++)num[i]=gi()+1;memset(T,0,sizeof T);for(int i=1;i<=n;i++){int now=num[i];update(now);L[i]=sum(now-1);}memset(T,0,sizeof T);for(int i=n;i;i--){int now=num[i];update(now);R[i]=sum(now-1);}long long ans=0;for(int i=1;i<=n;i++)ans+=L[i]*R[i];printf("%lld",ans);return 0; }
2、黃金礦工
Description
黃金礦工是一個經典的小游戲,它可以鍛煉人的反應能力。該游戲中,可以通過“挖礦”獲得積分并不斷升級。玩家可以在線玩flash版黃金礦工,也可以下載后玩單機版黃金礦工。目前,黃金礦工小游戲有多個版本,例如黃金礦工雙人版,黃金礦工單人版等。
Jimmy是一位黃金礦工,他所在的金礦是一個n*n的矩形區域(俯視),區域內有黃金、石頭和TNT,由一個 n*n的矩陣描述。黃金的價值對應矩陣中的正值,石頭的價值對應矩陣中的負值,TNT由0表示。換句話說,挖到黃金賺錢,石頭虧損,如果挖到TNT就掛了。
Jimmy租到的挖礦工具很特別,它的形狀是一個長寬任意(均為正整數)的矩形,可以取走被該工具覆蓋的矩形區域內的所有物品,但如果該區域內有TNT,該工具將被炸毀,此時Jimmy將不得不賠償礦主+∞元!!!需要注意的是,該工具只能在金礦范圍內使用(即不得超出金礦邊界),且租金為每次使用十元。
現在,Jimmy想知道,如果他至多只有一次租用該工具的機會,他能獲得的最大收益是多少。當然,如果Jimmy租用該工具無論如何都會虧損,他可以不租用,此時收益為0.
Input
第一行:一個整數n?
接下來n行,每行n個整數(絕對值<100),為題目中所描述的矩陣。
Output
一個數,即Jimmy所能獲得的最大收益。
Sample Input
3?
0 -1 -1?
0 -12 0?
-19 0 0
Sample Output
0
Hint
【樣例解釋】?
無論Jimmy怎么挖礦,挖到的不是石頭,就是TNT,總之無論如何都會虧損,所以選擇不租用工具,收益為0
【數據范圍】?
對于30%的數據:0<n<=10
對于60%的數據:0<n<=100
對于100%的數據:0<n<=300
TNT權值設為-∞就好了
DP。一維的最大數列滿足決策單調性,然后將二維的壓成一維的,n3次方過(考場上寫的n4次方,感謝ZJG大佬,%%%%%%%)(ZJG大佬今天要AK的,只是沒注意上方紅字,呵呵)(今天全是暴力還有第二,呵呵)
深入理解一下。這樣的矩陣:
當i==2 j==4時
被壓縮成了這樣。
再跑DP
#include<cstdio> #include<algorithm> #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); #define rg register using namespace std; int T[310][310],n; inline int gi() {rg int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0')f=(ch=='-')?-1:f,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*f; } inline int QT(int x,int y,int xx,int yy) {return T[xx][yy]-T[xx][y-1]-T[x-1][yy]+T[x-1][y-1]; } int main() {rg int num;n=gi();for(rg int i=1; i<=n; i++)for(rg int j=1; j<=n; j++) {num=gi();if(num==0)num=-10000000;T[i][j]=T[i-1][j]+num;}rg int ans=0;for(rg int i=1; i<=n; i++)for(rg int j=i; j<=n; j++) {int sum=T[j][1]-T[i-1][1];int Sum=sum;ans=max(ans,Sum);for(int k=2;k<=n;k++){sum=T[j][k]-T[i-1][k];if(Sum>0)Sum+=sum;else Sum=sum;ans=max(ans,Sum);}}ans=max(ans-10,0);printf("%d",ans);return 0; }
3、旅行
Description
Z小鎮是一個景色宜人的地方,吸引來自各地觀光客來此旅游觀光。Z小鎮附近共有N個景點(編號為1,2,3...N),這些景點被M條道路連接著,所有道路都是雙向的,兩個景點之間可能有多條道路連接著。也許是為了保護該地的旅游資源,Z小鎮有個奇怪的規定,就是對于一條給定的公路Ri,任何在該公路上行駛的車輛速度必須為Vi。速度變化太快使得游客們很不舒服,因此從一個景點前往另一個景點的時候,大家都希望選擇行使過程中最大速度和最小速度的比盡可能小的路線,也就是所謂最舒適路線。
Input
第一行包括兩個整數: N 和 M?
接下來的M行每行包含三個正整數: x,y和v。表示景點x到景點y之間有一條雙向公路,車輛必須以速度v在該公路上行駛。最后一行包含兩個正整數s,t,表示想知道從景點s到景點t最大最小速度比最小的路徑。s和t不可能相同。
Output
如果景點s到景點t沒有路徑,輸出“IMPOSSIBLE”。否則輸出一個數,表示最小的速度比。如果需要,輸出一個既約分數。
Sample Input
樣例1:?
4 2?
1 2 1?
3 4 2?
1 4?
樣例2:?
3 3?
1 2 10?
1 2 5?
2 3 8?
1 3?
樣例3:?
3 2?
1 2 2?
2 3 4?
1 3
Sample Output
樣例1:?
IMPOSSIBLE?
樣例2:?
5/4?
樣例3:?
2
Hint
0<N<=500;?
0<M<=5000;
把邊排個序,枚舉最小的邊(分母),再往上加邊并合并并查集,起點和原點在一起了就輸出當前權值。(%%%ZJG)
#include<cstdio> #include<algorithm> #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; const int maxn=510,maxm=5010<<1; inline int gi() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0')f=(ch=='-')?-1:f,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*f; } struct E {int a,b,w; } e[5001]; bool cmp(E a,E b) {return a.w<b.w; } int f[501]; inline int head(int r) {int A=r,B;while(A^f[A])A=f[A];while(r^A)B=f[r],f[r]=A,r=B;return A; } int main() {int n=gi(),m=gi();for(int i=1; i<=m; i++)e[i].a=gi(),e[i].b=gi(),e[i].w=gi();int s=gi(),t=gi();int ansa=2,ansb=20000000;sort(e+1,e+m+1,cmp);for(int i=1; i<=m; i++) {for(int j=1; j<=n; j++)f[j]=j;for(int j=i; j<=m; j++) {f[head(e[j].a)]=head(e[j].b);if(head(s)==head(t)) {if(e[i].w*ansb>ansa*e[j].w)ansa=e[i].w,ansb=e[j].w;break;}}}if(ansa==2&&ansb==20000000)printf("IMPOSSIBLE");else {int a=ansa,b=ansb,c;while(a%b)c=a%b,a=b,b=c;if(b^ansa)printf("%d/%d",ansb/b,ansa/b);else printf("%d",ansb/b);}return 0; } 4、奶牛跑步(K短路)Description
Bessie準備用從牛棚跑到池塘的方法來鍛煉. 但是因為她懶,她只準備沿著下坡的路跑到池塘,然后走回牛棚.
Bessie也不想跑得太遠,所以她想走最短的路經. 農場上一共有M(1<=M<=10,000)條路,每條路連接兩個用1..N(1<=N<=1000)標號的地點. 更方便的是,如果X>Y,則地點X的高度大于地點Y的高度. 地點N是Bessie的牛棚;地點1是池塘.
很快, Bessie厭倦了一直走同一條路.所以她想走不同的路,更明確地講,她想找出K(1<=K<=100)條不同的路經.為了避免過度勞累,她想使這K條路徑為最短的K條路徑.
請幫助Bessie找出這K條最短路經的長度.你的程序需要讀入農場的地圖, 一些從Xi到Yi的路徑和它們的長度(Xi,Yi,Di).?
所有(Xi,Yi,Di) 滿足( 1<=Yi<Xi; Yi<Xi<=N, 1<=Di<=1,000,000 ).
Input
第1行: 3個數: N,M,K?
第2..M+1行: 第 i+1行包含3個數 Xi,Yi,Di, 表示一條下坡的路.
Output
第1..K行: 第i行包含第i最短路徑的長度,或?1如果這樣的路徑不存在.如果多條路徑有同樣的長度,請注意將這些長度逐一列出.
Sample Input
5 8 7?
5 4 1?
5 3 1?
5 2 1?
5 1 1?
4 3 4?
3 1 1?
3 2 1?
2 1 1
Sample Output
1?
2?
2?
3?
6?
7?
-1
Hint
【樣例解釋】?
路徑分別為(5-1),(5-3-1),(5-2-1),(5-3-2-1),(5-4-3-1),(5-4-3-2-1)
裸A*+SPFA優化(考場上竟然寫了裸深搜,SPFA還為了,最后T1WA2,呵呵)
#include<cstdio> #include<algorithm> #include<queue> #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout); using namespace std; const int maxn=1010,maxm=10010<<1,maxk=110; int fir[maxn],nxt[maxm],dis[maxm],w[maxm],S[maxn],ans[maxk],rev[maxm]; int n,m,k,id; inline int gi() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0')f=(ch=='-')?-1:f,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*f; } inline void adde(int a,int b,int c,int d) {nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c,rev[id]=d; } struct node {int n,r; }; bool operator <(node me,node ot) {return S[me.n]+me.r>S[ot.n]+ot.r; } inline void AStar() {priority_queue<node>as;as.push((node) {n,0});int C=0;while(!as.empty()&&(C^k)) {int now=as.top().n,R=as.top().r;if(now==1) {++C;ans[++ans[0]]=R;} elsefor(int i=fir[now]; i; i=nxt[i])if(rev[i])as.push((node) {dis[i],R+w[i]});as.pop();} } inline void spfa() {int que[maxn],hd=1,tl=2;bool in[maxn]= {0};que[1]=1;in[1]=1;for(int i=2; i<=n; i++)S[i]=1000000000;while(hd^tl) {int f=que[hd];for(int i=fir[f]; i; i=nxt[i])if(!rev[i]) {if(S[f]+w[i]<S[dis[i]]) {S[dis[i]]=S[f]+w[i];if(!in[dis[i]])que[tl++]=dis[i],in[dis[i]]=1;}if(tl==1003)tl=1;}if(++hd==1003)hd=1;in[f]=0;} } int main() {n=gi(),m=gi(),k=gi();int a,b,c;for(int i=1; i<=m; i++) {a=gi(),b=gi(),c=gi();adde(a,b,c,1);adde(b,a,c,0);}spfa();AStar();for(int i=1; i<=ans[0]; ++i)printf("%d\n",ans[i]);for(int i=k-ans[0]; i; --i)printf("-1\n");return 0; }
最后%%%AK大神ZJG
總結
- 上一篇: Cisco 2960升级IOS
- 下一篇: 24孔复音口琴图