2018-2019賽季多校聯合新生訓練賽第五場(2018/12/14)補題題解
阿新 • • 發佈:2018-12-15
A 【字串】ISBN號碼(字串基礎)
字串基礎題,注意一下x的特判即可
程式碼
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); string a; int p=1,sum=0; cin>>a; for(int i=0;i<a.size()-1;i++) if(isdigit(a[i])) sum+=(a[i]-'0')*p++; sum%=11; if(sum==10) { if(a[a.size()-1]=='X') cout<<"Right"; else { for(int i=0;i<a.size()-1;i++) cout<<a[i]; cout<<'X'; } } else { if(char(sum+'0')==a[a.size()-1]) cout<<"Right"; else { for(int i=0;i<a.size()-1;i++) cout<<a[i]; cout<<char(sum+'0'); } } }
B 第N個智慧數(數學)
打表題
解法
把所有的平方差都列舉一下
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
cout<<i*i-j*j;
這樣還會出現重複的項,並且還是亂序的,我是打出表來之後再把他們放到set中進行進行去重與排序然後輸出即可
程式碼
#include <bits/stdc++.h> using namespace std; int bk[]={這裡是打表}; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); set<int> st; for(int i=0;i<4950;i++) st.insert(bk[i]); int n,sum=0; cin>>n; for(auto it=st.begin();it!=st.end();it++) { sum++; if(sum==n) { cout<<*it; break; } } }
C 第m大的身份證號碼(字串基礎)
這個把他們用個sort排序一下就可以了
程式碼
#include <bits/stdc++.h> using namespace std; string num[1666],num1[666]; bool cmp(string a,string b) { string t1="",t2=""; for(int i=6;i<=13;i++) t1+=a[i]; for(int i=6;i<=13;i++) t2+=b[i]; return t1<t2; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,k; cin>>n>>k; for(int i=0;i<n;i++) cin>>num[i]; sort(num,num+n,cmp); cout<<num[k-1]; }
D 鋸木棍(模擬)
這個題直接模擬即可
解法
因為塗色,所以我們可以把這個木塊當一個桶,塗色等於桶上的點放入了東西。因為塗兩種顏色且兩種顏色都是長度的約數,因此我們可以直接進行掃描
第一遍掃描掃最大值
第二遍掃描掃等於最大值的數量
程式碼
#include <bits/stdc++.h>
using namespace std;
int bk[100015];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int l,m,n,maxn=-1,sum=0,ans=0;
cin>>l>>m>>n;
int s1=l/m;
int s2=l/n;
for(int i=1;i<=l;i++)
if(i%s1==0)
bk[i]=1;
for(int i=1;i<=l;i++)
if(i%s2==0)
bk[i]=1;
for(int i=1;i<=l;i++)
{
if(bk[i]==0)
sum++;
else
{
sum++;
maxn=max(maxn,sum);
sum=0;
}
}
for(int i=1;i<=l;i++)
{
if(bk[i]==0)
sum++;
else
{
sum++;
if(sum==maxn)
ans++;
sum=0;
}
}
cout<<maxn<<" "<<ans;
}
E 座標統計(基礎程式設計能力)
直接放入然後掃描比較即可
程式碼
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
}zb[10000];
int sum[10000];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,maxn=-1,id;
cin>>n;
for(int i=0;i<n;i++)
cin>>zb[i].x>>zb[i].y;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(zb[j].x<zb[i].x&&zb[j].y<zb[i].y)
sum[i]++;
for(int i=0;i<n;i++)
{
if(sum[i]>=maxn)
{
maxn=sum[i];
id=i+1;
}
cout<<sum[i]<<"\n";
}
cout<<id;
}
F 列印月曆(基礎程式設計能力)
可能這個題分到基礎程式設計能力有點感覺不大合適,但是這個題確實沒有別的什麼難的知識點只是需要注意一些地方
解法
①首先就是這個閏年的問題,閏年的2月還平年的2月是不一樣的
②然後是計算這月距離第一個月的第一天有幾天
③然後推出這個月的第一天是在星期幾
int t=(sum)%7;
int day=(n+t-1)%7+1;
其中day變數就是星期幾
④之後再算出這個月具體多少天,這個還得分閏年和平年
⑤然後按照1到這個月的天數輸出即可(這裡之前還要把那些空格打印出來)
⑥注意第一行一定沒有空行要不格式錯誤(測試資料 2015 2 4)
⑦還有數字用%-4d
程式碼
#include <bits/stdc++.h>
using namespace std;
int month[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
int main()
{
/*ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);*/
int y,m,n,yn;
cin>>y>>m>>n;
cout<<"S M T W T F S\n";
if(y%4==0&&y%100!=0||y%400==0)
yn=1;
else
yn=0;
int c=m-1,mth,sum=0;
for(int i=1;i<c+1;i++)
{
if(i==2)
{
if(yn)
sum+=29;
else
sum+=28;
}
sum+=month[i];
}
int t=(sum)%7;
int day=(n+t-1)%7+1;
for(int i=0;i<(day%7)*4;i++)
cout<<" ";
if(m==2)
{
if(yn)
mth=29;
else
mth=28;
}
else
mth=month[m];
int ft=1;
for(int i=1;i<=mth;i++)
{
if(day==7)
{
if(!ft)
cout<<"\n";
day=0;
}
printf("%-4d",i);
day++;
ft=0;
}
}
G 分割繩子(二分查詢)
這個地方比賽的時候,都已經做出來了,就是因為二分查詢帶小數的東西有些細節不會找,導致的出現了問題
對於小數點的精度問題,我們不能單純的用l<=r而是用帶精度的
這個題我們要精確到小數點後兩位,那麼我們可以用
while(l<=r-0.001)
//do something
其中mid也是double的,之前l=mid+1也變成了l=mid+0.001 r也相同的道理
這個題原題應該沒有什麼問題吧,裸二分查詢
判斷函式也是判斷一下當前mid值能分割出幾個繩子即可
程式碼
#include <bits/stdc++.h>
using namespace std;
double num[1005];
int n,k;
int isok(double m)
{
int sum=0;
for(int i=0;i<n;i++)
sum+=num[i]/m;
return sum>=k;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
double l=0,r;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>num[i],r=max(r,num[i]);
while(l<=r-0.001)
{
double mid=(l+r)/2;
if(isok(mid))
l=mid+0.001;
else
r=mid-0.001;
}
printf("%.2f",l-0.001);
}
H 換座位(語法基礎)
排序一次跟原來比較一下看哪裡不一樣了
程式碼
#include <bits/stdc++.h>
using namespace std;
int num[666],num1[666];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,sum=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>num[i],num1[i]=num[i];
sort(num,num+n);
for(int i=0;i<n;i++)
if(num[i]!=num1[i])
sum++;
cout<<sum;
}
I 找M進位制數(字串基礎)
這個題我還因為細節問題罰時兩次
需要注意的細節
①十進位制以下是否出現了字母或者大於等於當前進位制的數
②十進位制以上是否出現了大於等於當前進位制的字母
③第一位數字是否為0(聽說這個資料中好像沒有給出)、
程式碼
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
}zb[10000];
int sum[10000];
string st[100005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,maxn=-1,id;
cin>>n>>id;
int ans=n;
for(int i=0;i<n;i++)
cin>>st[i];
for(int i=0;i<n;i++)
for(int j=0;j<st[i].size();j++)
{
if(st[i][0]=='0')
{
ans--;
break;
}
if(id<=10)
{
if(isalpha(st[i][j]))
{
ans--;
break;
}
if(isdigit(st[i][j]))
{
if(st[i][j]-'0'>id-1)
{
ans--;
break;
}
}
}
if(id>10)
{
if(isalpha(st[i][j]))
{
if(st[i][j]>'A'+id-11)
{
ans--;
break;
}
}
}
}
cout<<ans;
}
J 迴圈小數(字串模擬)
這個題並不難啊,比起紫書上那個90年代的acm世界決賽的真題來說還是太嫩了點
解法
①找出迴圈節前的小數
②找出迴圈節
③把迴圈節迴圈多次加到迴圈節前的小數後面(這裡一定要比給定的要找的位數要多)
④按照要求輸出即可
程式碼
#include <bits/stdc++.h>
using namespace std;
int bk[100015];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,f=0,ff=0;
cin>>n;
string a,nu="",xh="";
cin>>a;
for(int i=0;i<a.size();i++)
{
if(a[i]=='.')
f=1;
if(a[i]=='(')
ff=1;
if(f&&!ff)
{
if(isdigit(a[i]))
nu+=a[i];
}
if(f&&ff)
{
if(isdigit(a[i]))
xh+=a[i];
}
}
for(int i=0;i<100005;i++)
nu+=xh;
cout<<nu[n-1];
}
K 單純質因數(數論)
待填坑我這個玩意-6都還不知道錯在哪裡,感覺寫對了啊
L 安裝飲水機(目前不明)
待填坑
M 分木塊(語法基礎)
程式碼
#include <bits/stdc++.h>
using namespace std;
int num[666],num1[666];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,sum=0,r1=0,r2=0,r3=0;
cin>>n;
for(int i=0;i<n;i++)
{
int t,ans1=0,ans2=0,ans3=0;
cin>>t;
ans1+=t/100;
t%=100;
ans2+=t/10;
t%=10;
ans3+=t;
r1+=ans1;
r2+=ans2;
r3+=ans3;
}
cout<<r1<<"\n"<<r2<<"\n"<<r3;
}
N 活動人數(語法基礎)
程式碼
#include <bits/stdc++.h>
using namespace std;
int num[1666],num1[666];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,sum=0,r1=0,r2=0,r3=0,l,k;
cin>>n>>l>>k;
for(int i=0;i<n;i++)
cin>>num[i];
sort(num,num+n);
for(int i=0;i<n;i++)
if(1)
{
if(l>=num[i])
{
sum++;
l+=k;
}
}
cout<<sum;
}