1. 程式人生 > 其它 >吉首大學第十屆“新星杯”大學生程式設計大賽(暨新生網路同步賽)

吉首大學第十屆“新星杯”大學生程式設計大賽(暨新生網路同步賽)

技術標籤:吉首大學演算法程式設計

吉首大學第十屆“新星杯”大學生程式設計大賽(暨新生網路同步賽)

連結

小結:就過了七題(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;
	}
} 

最後,有好方法歡迎大家一起討論哈。