【jzoj】2018.1.31 NOIP普及组——D组模拟赛
前言
今天題目比較水and我進了C組,不過太太太太太太太太太太太太太太太太絕望了QAQ。所以我也沒有做C組的題。寫完博客我就做O(∩_∩)O。
正題
題1:奇數統計(jzoj1547)
就是輸入n個數,輸出出現次數為奇數的一個數(只有一個)。
輸入
第一行是N,下一行有N個正整數。
輸出
出現了奇數次的數。
樣例輸入
9
3 1 2 2 17 1 3 17 3
樣例輸出
3
桶不解釋
代碼
#include<cstdio> #include<iostream> using namespace std; int n,a[10001],x,ans; int main() {//freopen("count.in","r",stdin);//freopen("count.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&x);a[x]++;} for (int i=1;i<=10000;i++) if (a[i]%2==1) {printf("%d",i);return 0;} }相信我不加批注你們也懂不O(∩_∩)O
題2:有理逼近(jzoj1548)
輸入
輸入文件的第一行為P、N,其中 P、N<30000。
輸出
輸出文件只有一行,格式為“X/Y U/V”。注意,答案必須是既約的,也就是說分子、分母的最大公約數必須等于1。
樣例輸入
2 5
樣例輸出
4/3 3/2
暴枚好像會超時,所以我們先枚舉分子,然后從中間開始向兩邊擴展的搜分母。
在這里感謝朋友提供思路,這里是他的博客:http://blog.csdn.net/sugar_free_mint
代碼
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> using namespace std; double p,s1,s2,ss1,ss2,j,k; int w,n,u; int main() {//freopen("rational.in","r",stdin);//freopen("rational.out","w",stdout);scanf("%d%d",&w,&n);p=sqrt(w);//開方u=n/p;//確定中間值s1=-214748364;s2=1;ss1=214748364;ss2=1;//初始化for (double i=1;i<=n;i++){j=u;k=0;while (j+k<=n && j-k>=1){if (p-i/(j+k)>0 && p-i/(j+k)<p-s1/s2)//判斷{s1=i;s2=(j+k);}if (p-i/(j-k)>0 && p-i/(j-k)<p-s1/s2){s1=i;s2=(j-k);}if (i/(j+k)-p>0 && i/(j+k)-p<ss1/ss2-p){ss1=i;ss2=(j+k);}if (i/(j-k)-p>0 && i/(j-k)-p<ss1/ss2-p){ss1=i;ss2=(j-k);}k++;}//擴展}s1=int(int(s1)/__gcd(int(s1),int(s2)));s2=int(int(s2)/__gcd(int(s1),int(s2)));//約分ss1=int(int(ss1)/__gcd(int(ss1),int(ss2)));ss2=int(int(ss2)/__gcd(int(ss1),int(ss2)));//約分printf("%.lf/%.lf %.lf/%.lf",s1,s2,ss1,ss2);//輸出 }題目3:活動安排(jzoj1549)
有n (n<=100) 個活動,每個活動開始時間si,結束時間fi。每個活動需要一個會場,求需要的最小會場數。水題。
輸入
第一行是活動數n(1≤n≤100)。
以后的n行,每行兩個整數,分別表示n個活動的開始時間si和結束時間fi(1≤i≤n),si
輸出
一個整數,表示需要的最少會場數。
樣例輸入
4
1 8
2 5
7 15
5 9
樣例輸出
3
判斷當前有沒有空的會場,如果有就把活動安排進去,不然就開一個新的。
代碼
#include<cstdio> using namespace std; int s[101],f[101],n,t,w,wf[101]; int main() {//freopen("meet.in","r",stdin);//freopen("meet.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d%d",&s[i],&f[i]);for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++)if (s[i]>s[j]){t=s[i];s[i]=s[j];s[j]=t;t=f[i];f[i]=f[j];f[j]=t;}//看我連快排都懶得用了for (int i=1;i<=n;i++){for (int j=1;j<=w;j++)if (s[i]>=wf[j])//有空會場{wf[j]=f[i];f[i]=-1;break;}if (f[i]!=-1)//安排新會場{w++;wf[w]=f[i];//活動結束時間}}printf("%d",w);//輸出 }題目4:最小步數(jzoj1550)
一條路長n,每走到一個格會獲得Ai元(-10000<=Ai<=10000),你也可以選擇花100元跳過該格,金幣不可以為負數。求到終點最小的步數
輸入
共有兩行。
第一行為整數N(0<=N<=100)。
第二行有N個整數,第K個數為A[K],-10000<=A[K]<=10000,。
輸出
一個整數,表示需要走的最少步數。若無法走到終點,輸出-1。
樣例輸入
6
30 30 30 30 30 30
樣例輸出
5
這里dp,其實記搜也可以過(不過不重要)。然后用f[i][j]來表示到達第i格用j步并且最后一步是跳過的最大金幣,然后用f[i][j]來表示到達第i格用j步并且最后一步是走過的最大金幣。
動態轉移方程:f[i][j]=max(f[i-1][j],f2[i-1][j])-100 (跳過該步)
f2[i][j]=max(f[i-1][j-1],f2[i-1][j-1])+a[i] (走過該步)
代碼
#include<cstdio> #include<iostream> using namespace std; int a[101],f[101][101],n,ans,f2[101][101]; int main() {//freopen("steps.in","r",stdin);//freopen("steps.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&a[i]);} for (int i=1;i<=n;i++)for (int j=0;j<=i;j++) {f2[i][j]=-214748364;f[i][j]=-214748364;}//初始化 for (int i=1;i<=n;i++){for (int j=1;j<=i;j++){if (max(f[i-1][j],f2[i-1][j])-100>=0 && i!=n) f[i][j]=max(f[i-1][j],f2[i-1][j])-100;//跳if (max(f[i-1][j-1],f2[i-1][j-1])+a[i]>=0) f2[i][j]=max(f[i-1][j-1],f2[i-1][j-1])+a[i];//走}}for (int i=0;i<=n;i++) if (f2[n][i]>=0) {printf("%d",i);return 0;}//查找printf("-1");//不能到達 }總結
以上是生活随笔為你收集整理的【jzoj】2018.1.31 NOIP普及组——D组模拟赛的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【jzoj】2018.1.30NOIP普
- 下一篇: 【jzoj3734,Usaco2014O