2018-2019賽季多校聯合新生訓練賽第七場(2018/12/16)補題題解
阿新 • • 發佈:2018-12-17
感慨
這次還是有不少題挺靠思維的
A 面積(語法基礎)
這個公式都記得啊應該就是S=(上底+下底)*高/2
程式碼
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int a,b,c;
cin>>a>>b>>c;
int ans=(a+a+2*c)*b/2;
cout<<ans;
}
B 網路訊號(語法基礎)
都是在一條直徑上走,那不就是一個數軸上走閉區間麼?
程式碼
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int r,n,ans=0,re=0; cin>>r>>n; for(int i=0;i<n;i++) { int t; cin>>t; re+=t; if(re>=-r&&re<=r) ans++; } cout<<ans; }
C 排隊I(思維)
這個資料到了1e5,樸素的O(N*N)的演算法絕對是要超時的,那麼應該怎麼辦呢?
實際上就一句話,掃一遍,把之前出現的陣列放到bk數組裡面,然後遍歷當前數比這個數大的bk陣列的數值,加起來。
加起來的意思就是之前已經記錄了多少個比他大的數,這樣就是線性的時間了
程式碼
#include <bits/stdc++.h> using namespace std; int bk[1200]; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n; cin>>n; for(int i=0;i<n;i++) { int t,sum=0; cin>>t; bk[t]++; for(int j=t+1;j<=120;j++) sum+=bk[j]; cout<<sum<<" "; } }
D 覆蓋(模擬)
這個題有不少細節我就說一下我的思路,具體細節還是自己研究研究就行
①先算男生拖的地,這個時候女生還沒有拖地,所以直接算一行的
②然後再算女生拖的,女生拖的地是男生沒有脫的行數*女生覆蓋的列數
③如果男生不拖,是0,那麼就直接算女生的
④具體的標記可以在每行每列給出
程式碼
#include <bits/stdc++.h>
using namespace std;
int bk[5005][5005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,b,g,sum=0,ans1=0;
cin>>n>>m>>b>>g;
for(int i=0;i<b;i++)
{
int x,y;
cin>>x>>y;
for(int j=x;j<=y;j++)
bk[j][0]++;
}
for(int i=0;i<g;i++)
{
int x,y;
cin>>x>>y;
for(int j=x;j<=y;j++)
bk[1][j]++;
}
if(b>0)
{
for(int i=1;i<=n;i++)
if(bk[i][0]==0)
ans1++;
sum+=m*(n-ans1);
for(int i=1;i<=m;i++)
if(bk[1][i])
sum+=ans1;
cout<<sum;
}
else
{
for(int i=1;i<=m;i++)
if(bk[1][i])
sum+=n;
cout<<sum;
}
}
E 遊戲(模擬)
先算出最小公倍數,作為最小週期數,然後算出最小週期內贏的次數,再把餘下的加上就行了
程式碼
#include <bits/stdc++.h>
using namespace std;
int num1[1000];
int num2[1000];
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int check(int a,int b)
{
if(a==1)
{
if(b==2)
return 1;
else return 0;
}
if(a==2)
{
if(b==3)
return 1;
else return 0;
}
if(a==3)
{
if(b==1)
return 1;
else return 0;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,k,sum=0,ans=1;
cin>>n>>m>>k;
int t=n*m/gcd(n,m);
for(int i=1;i<=n;i++)
cin>>num1[i];
for(int i=1;i<=m;i++)
cin>>num2[i];
for(int i=1;i<=t;i++)
{
if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
sum++;
}
if(k<=t)
{
for(int i=1;i<=k;i++)
{
if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
ans++;
}
cout<<ans;
}
else
{
ans*=(k/t)*sum;
k%=t;
for(int i=1;i<=k;i++)
{
if(check(num1[(i-1)%n+1],num2[(i-1)%m+1]))
ans++;
}
cout<<ans;
}
}
F 差(思維)
又是一個樸素O(N*N)超時的題,還得尋找別的方法
實際上這裡去記錄每個差值的數,然後加上這個差值所包含的數,因為資料給出就是升序的,所以不用排序,然後把每次數的數量記錄一下
注意如果差值是一個負數那麼可以不用記錄,因為那樣沒有什麼意義
例如樣例
4 1
1 1 2 2
1-1=0
sum+=bk[0]=0
bk[1]=1
表明1已經出現了1次了
1-1=0
sum+=bk[0]=0
bk[1]-2
表明1已經出現了2次了
2-1=1
sum+=bk[1]=2
bk[2]=1
2-1=1
sum+=bk[1]=4
bk[2]=2
所以答案是4
程式碼
#include <bits/stdc++.h>
using namespace std;
map<long long,long long> bk;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long n,c,sum=0;
cin>>n>>c;
for(int i=0;i<n;i++)
{
int t;
cin>>t;
if(t-c>=0)
sum+=bk[t-c];
bk[t]++;
}
cout<<sum;
}
G 成績統計(語法基礎)
程式碼
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,you=0,liang=0,zhong=0,cha=0;
cin>>n;
for(int i=0;i<n;i++)
{
int t;
cin>>t;
if(t>=90&&t<=100)
you++;
else if(t>=80&&t<=89)
liang++;
else if(t>=60&&t<=79)
zhong++;
else if(t<60)
cha++;
}
cout<<"You "<<you<<"\n";
cout<<"Liang "<<liang<<"\n";
cout<<"Zhong "<<zhong<<"\n";
cout<<"Cha "<<cha<<"\n";
}
H 列印圖形II(語法基礎)
程式碼
#include <bits/stdc++.h>
using namespace std;
string st[12321];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,you=0,liang=0,zhong=0,cha=0;
cin>>n;
for(int i=n;i;i--)
{
string t="",tt="",ttt="";
for(int j=i;j;j--)
t+=char('A'+n-j);
for(int j=0;j<t.size()-1;j++)
tt+=t[j];
reverse(tt.begin(),tt.end());
for(int j=0;j<n-i;j++)
ttt+=' ';
st[i]=ttt+t+tt;
}
for(int i=n;i;i--)
cout<<st[i]<<"\n";
for(int i=2;i<=n;i++)
cout<<st[i]<<"\n";
}
I 數值計算(基礎程式設計)
直接暴力啊,這個題資料這麼小
程式碼
#include <bits/stdc++.h>
using namespace std;
string st[12321];
int isp(int n)
{
for(int i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}
int check(int n)
{
double a=sqrt(n);
int b=sqrt(n);
if(a==b)
return 1;
else
return 0;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int l,r,sum=0;
cin>>l>>r;
for(int i=l;i<=r;i++)
{
if(!isp(i))
continue;
stringstream s;
s<<i;
string te,t1="",t2="";
s>>te;
t1+=te[0];t1+=te[1];
t2+=te[2];t2+=te[3];
stringstream ss,sss;
ss<<t1;sss<<t2;
int n1,n2;
ss>>n1;sss>>n2;
if(check(n1)&&check(n2))
cout<<i<<"\n",sum++;
}
cout<<sum;
}
J 字串VII(字串基礎)
這題還因為沒有看清楚插入的位置錯了兩次
程式碼
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string a;
cin>>a;
int t;
cin>>t;
string b;
cin>>b;
cout<<a.size()<<"\n"<<a.find("a")+1<<"\n";
a.insert(t-1,b);
cout<<a;
}
K 身高排隊(排序)
注意這裡有個四捨五入,別的應該沒啥特別的了
程式碼
#include <bits/stdc++.h>
using namespace std;
int num[2333][2333],st[23333333];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,p=0,ans=0;
double sum=0;
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>num[i][j],st[p++]=num[i][j],sum+=num[i][j];
for(int i=0;i<m;i++)
{
int maxn=-1;
for(int j=0;j<n;j++)
{
if(num[j][i]>maxn)
maxn=num[j][i];
}
cout<<maxn<<"\n";
}
double avg=sum/(n*m);
avg+=0.5;
int ag=int(avg);
sort(st,st+p,cmp);
for(int i=0;i<p;i++)
{
if(st[i]>=ag)
ans++;
cout<<st[i]<<" ";
}
cout<<"\n"<<ag<<"\n"<<ans;
}
L 階乘後K位(數學)
這個題,我在比賽的時候差點做出來了,因為一個細節沒有注意
我直接乘冪然後餘的100億發現這樣也不對,然後把最後的10位拿掉也不對,實際上階乘最後會出現一堆0,而題目又要去掉最終答案的0.
因為0對於乘數來說沒有任何貢獻,所以我們應該先把0去掉然後再進行餘10億,最後注意一下高位補0,其他的就沒啥了
程式碼
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,k;
cin>>n>>k;
long long ans=1;
for(int i=1;i<=n;i++)
{
ans*=i;
while(ans%10==0)
ans/=10;
ans%=10000000000;
}
stringstream s;
s<<ans;
string ss;
s>>ss;
for(int i=ss.size();i<k;i++)
ss='0'+ss;
for(int i=ss.size()-k;i<ss.size();i++)
cout<<ss[i];
}
M 尋找指定的特殊素數(數學)
超級大水題,根本到不了100就要error,這次還因為題目裡的歎號是中文的標點,而上傳的歎號是英文的,這個弄的我這個題一血沒了,過了一個小時才猜出來這裡可能有錯,期間還交了1 2次,加了幾次罰時
具體我是打表做的,至於怎麼打表,直接暴力就可以了。篩出來素數然後一點一點的暴力,打表很快的
打表的程式碼
#include <bits/stdc++.h>
using namespace std;
int bk[100000005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
for(int i=2;i*i<=100000000;i++)
if(!bk[i])
for(int j=i*i;j<=100000000;j+=i)
bk[j]=1;
bk[1]=1;
for(int k=1;k<=8;k++)
{
int n,m,l=1,ff=0,sum=0;
for(int i=0;i<k-1;i++)
l*=10;
for(int i=l;i<=l*10;i++)
{
if(bk[i])
continue;
int k=i,f=0;
k/=10;
while(k)
{
if(bk[k])
{
f=1;
break;
}
k/=10;
}
if(!f)
sum++,cout<<i<<",";
/*if(sum==m)
{
cout<<i;
ff=1;
break;
}*/
}
cout<<"\n"<<sum<<"\n";
}
}
提交的程式碼
#include <bits/stdc++.h>
using namespace std;
int db1[]={2,3,5,7};
int db2[]={23,29,31,37,53,59,71,73,79};
int db3[]={233,239,293,311,313,317,373,379,593,599,719,733,739,797};
int db4[]={2333,2339,2393,2399,2939,3119,3137,3733,3739,3793,3797,5939,7193,7331,7333,7393};
int db5[]={23333,23339,23399,23993,29399,31193,31379,37337,37339,37397,59393,59399,71933,73331,73939};
int db6[]={233993,239933,293999,373379,373393,593933,593993,719333,739391,739393,739397,739399};
int db7[]={2339933,2399333,2939999,3733799,5939333,7393913,7393931,7393933};
int db8[]={23399339,29399999,37337999,59393339,73939133};
int c[100];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
c[1]=4,c[2]=9,c[3]=14,c[4]=16,c[5]=15,c[6]=12,c[7]=8,c[8]=5;
if(m>c[n])
cout<<"Error!";
else
{
if(n==1)
cout<<db1[m-1];
if(n==2)
cout<<db2[m-1];
if(n==3)
cout<<db3[m-1];
if(n==4)
cout<<db4[m-1];
if(n==5)
cout<<db5[m-1];
if(n==6)
cout<<db6[m-1];
if(n==7)
cout<<db7[m-1];
if(n==8)
cout<<db8[m-1];
}
}