吉首大學第十屆“新星杯”大學生程式設計大賽(暨新生網路同步賽)
阿新 • • 發佈:2020-12-29
吉首大學第十屆“新星杯”大學生程式設計大賽(暨新生網路同步賽)
小結:就過了七題(A、B、C、E、J、K、L),有幾題感覺能寫出來,但總感覺複雜就沒寫了哈哈哈。有幾題方法有點笨,就別看了哈哈,不知道有沒有題解,讓我感受下大佬的思想-。
A:學習快速冪
這題其實就是找找規律,你把1 2 3 4 5 6 7 8 9 10…都算下就能發現規律了。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
long long ksm( long long a,long long n)
{
long long ans=1;
while(n)
{
if(n&1)
ans*=a;
a*=a;
n>>=1;
}
return ans;
}
int main()
{
long long t,n;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
long long i,sum=1;
if(n<=2)
{
if(n==0)
printf("0\n" );
else if(n==1)
printf("1\n");
else
printf("4\n");
}
else
{
for(i=1;i<100;++i)
{
if(ksm(2,i)>n)
break;
sum+=ksm(2,i+1)-1;
int j=ksm(2,i)-ksm(2,i-1)-1;
sum+=j*(2*ksm(2,i)+j-1)/2;
}
int j=n-ksm(2,i-1);
sum+=j*(2*ksm(2,i)+j-1)/2;
printf ("%lld\n",sum);
}
}
}
B:算數之王
說實話這題我寫得很複雜,還是別看了…不過這還是第一次寫這種組合過程,收穫還是有的。有沒有簡單的方法,望大佬提點一下
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[20];
int vis[20],b[200];
int f,sum,n,t,ans;
void dfs(int ret,int s)
{
if(s>sum)
return;
if(s==sum)
{
f=1;return;
}
for(int i=ret+1;i<n;++i)
{
if(vis[i]==1)
continue;
dfs(i,s+a[i]);
if(f==1)
return;
}
}
void df(int ret)
{
for(int i=ret+1;i<n;++i)
{
vis[i]=1;
sum+=a[i];f=0;
for(int j=0;j<n;++j)
if(vis[j]==0)
dfs(j,a[j]);
if(f){
b[sum]=1;ans=max(ans,sum);
}
df(i);
sum-=a[i];
vis[i]=0;
}
}
int main()
{
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
int ret=0;
ans=0;
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i];
for(int i=0;i<n;++i)
{
memset(vis,0,sizeof(vis));
sum=a[i];
f=0;vis[i]=1;
for(int j=0;j<n;++j)
if(vis[j]==0)
dfs(j,a[j]);
if(f){
b[sum]=1;ans=max(ans,sum);
}
df(i);
}
for(int i=0;i<200;++i)
if(b[i]==1)
ret++;
cout<<ret<<" "<<ans<<endl;
}
}
C:LeeLdler的數字
這題很簡單…用立方和公式化簡一下式子你就發現了…
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
cin>>n;
cout<<1<<" "<<n-1;
}
E:會長的榜單
簡單題
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
int main()
{
string a;
int n;
cin>>n>>a;
cout<<a<<" ";
while(n--)
{
int h,m,s;
cin>>s;
h=s/3600,s%=3600;
m=s/60,s%=60;
if(h==0&&m==0&&s==0)
printf("0 ");
else
printf("%02d:%02d:%02d ",h,m,s);
}
}
J:會長數
簡單題
#include<iostream>
#include<string>
using namespace std;
int a[1000];
int b[100];
int main()
{
int ret=0;
a[1]=1;
for(int i=2;i<200;++i)
for(int j=2;i*j<200;++j)
a[i*j]=1;
for(int i=10;i<=100;++i)
{
if(a[i]==0)
{
int sum=0,f=1,t=i;
while(t)
{
if(a[t%10]!=0)
f=0;
sum+=t%10;
t/=10;
}
if(f==1&&a[sum]==0)
b[ret++]=i;
}
}
cout<<ret<<endl;
for(int i=0;i<ret;++i)
{
cout<<b[i];
if(i!=ret-1)
cout<<" "<<endl;
}
}
K:抽獎
看懂題目就行了…
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int a[2000];
int main()
{
int n,m,x,sum=0;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i];
sum+=a[i];
}
cin>>m;
int f=1;
double s1,s2;
for(int i=0;i<m;++i)
{
cin>>x;
s1=(a[x]*1.0)/sum;
int ans=0;
for(int j=1;j<=n;++j)
ans=max(ans,a[j]);
s2=(ans*1.0)/sum;
if(s2-s1>0.2)
f=0;
a[x]--;
sum--;
}
if(f)
cout<<"PASS";
else
cout<<"BUG";
}
L:饞嘴會長逛小吃街
這題模擬一下就會發現,其實就是找連續k個攤位之間的差值和最小,然後乘以2就行
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[200];
int main()
{
int t;
cin>>t;
while(t--)
{
int ans=99999999,n,k;
cin>>n>>k;
for(int i=0;i<n;++i)
cin>>a[i];
sort(a,a+n);
for(int i=0;i<=n-k;++i)
{
int sum=0;
for(int j=i+1;j<i+k;++j)
sum+=a[j]-a[j-1];
ans=min(ans,sum*2);
}
cout<<ans<<endl;
}
}
最後,有好方法歡迎大家一起討論哈。