A題
題目大意:給你N個數的序列,只有5或0;問你能組成的最大的能被90整除的數是多少,如果沒有輸出0;
解法:
好吧,其實這是個水題,首先因為是除90,所以,如果沒有0那肯定是輸出-1的,只要有0,至少可以保證不會輸出-1。。。
然後因為有0,所以我們把問題轉換成整除9的最大數,9這個數字比較奇葩,能整除它的一個必要條件是,這個數的數位和也能被9整除。
所以問題就很簡單了,統計5的個數,從最高數開始往下降,直到5*K能被9整除就可以,代碼如下。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>using namespace std;int main(){ int n,x,y,a; cin>>n; x=y=0; for(int i=0;i<n;i++) { cin>>a; if(a) x++; else y++; } if(!y) puts("-1"); else{ int ans=x; while (ans>=1 && (ans*5) %9!=0) ans--; if(ans){ for(int i=ans;i>=1;i--) cout<<5; for(int i=y;i>=1;i--) cout<<0; cout<<endl; } else puts("0"); } return 0;}
B題
題目大意:給你一個數字序列,統計裡面相同數位位置構成等差數列的個數。
解法:
首先,請允許我做一個悲傷的表情,我艸。。。
我因為沒有按要求輸出個數而WR在第一個範例兩次,而我自己死活沒看出來。
這題。。。沒什麼好說的,類比然後注意題目意思就行了,如果出現一次,那麼它是要輸出的,如果出現多次但不不構成等差數列,它是不能輸出的。
我在代碼裡加了注釋,看代碼吧
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <vector>using namespace std;const int maxn=100100;int flag[maxn]; //判斷這個數字是不是第一次出現int t[maxn]; //把出現過的數字全存在裡面struct node{ int c; //c表示這個數位前一個位置、d表示公差,flag用於判斷最後它是否要輸出 int d; bool flag; }D[maxn];int main(){ int n,x,len=0; cin>>n; memset(D,0,sizeof(D)); memset(flag,0,sizeof(flag)); memset(t,0,sizeof(t)); for(int i=1;i<=n;i++) { scanf("%d",&x); if(!flag[x]) { t[len++]=x; flag[x]=1; D[x].c=i; D[x].d=0; D[x].flag=false; } else { if(D[x].d==0) { D[x].d=i-D[x].c; D[x].c=i; } else { if(i-D[x].c==D[x].d) D[x].c=i; else D[x].flag=true; //如果不是第一次出現,並且不符合等差數列了,把flag標記 } } } sort(t,t+len); //cout<<len<<endl; int ans=0; for(int i=0;i<len;i++) { int xx=t[i]; if(!D[xx].flag) ans++; } cout<<ans<<endl; for(int i=0;i<len;i++) { int xx=t[i]; if(!D[xx].flag) printf("%d %d\n",xx,D[xx].d); } return 0;}
C題目
題目大意:給你2*N個浮點數,可以向下取整跟向上取整,向下跟向上的次數都是N,問最後取前與取後的最小的差,絕對值
解法:
後面一小時沒能出C,最後一分鐘交了下,WR在第五個範例,用dp寫的,沒過
ORZ,看大牛代碼都是不明覺厲的趕腳,都數組都不用開。。。。。不過我也看見有用dp過的。。。
然後看了看。。。發現懂了,不太好說,代碼有注釋,看代碼吧
#include <algorithm>#include <cstdio>#include <string>#include <iostream>using namespace std;const int INF=0x7fffffff;int main() {int n; cin>>n;int sum = 0;int zero = 0;for (int i = 0; i < 2*n; i++) {int x;scanf("%*d.%d", &x); //%*d的意思是輸入一個數,但是忽略它sum += x;if (x == 0) zero++;}/*先預設全部向下取整,所以兩著相差的絕對值就是sum*/int ans = INF; /*然後枚舉非零數向上取整的次數,從0到N*/for (int k =0; k<=n; k++) { if(k+zero<n) continue; //首先必須要滿足至少有N個數向下取整,才能去枚舉ans = min(ans, abs(k*1000-sum));}printf("%d.%03d\n", ans/1000, ans%1000);return 0;}