1. 程式人生 > 其它 >【總結】紀中Day5比賽總結

【總結】紀中Day5比賽總結

紀中Day5比賽總結


今天比賽突然蹦進了前十,連我自己都不敢相信(今天考那麼好,明天rp必定爆掉

T1



看到這道題的第一眼,我以為要用DFS來做,又看到有一個最後必須回到道路,覺得有些難度,先去做了T3。
回來後,仔細看了一下題目,發現題中有下面這句話:

先找出花生最多的植株,去採摘它的花生;然後再找出剩下的植株裡花生最多的,去採摘它的花生

所以,這道題可以用暴力來做。用一個結構體儲存植株的花生個數和它的座標,然後以花生的個數從大到小排序。排完序後,從最大的開始,列舉從當前點到每一棵植株並且採摘、返回到路旁的時間是否足夠,如果不足夠,直接退出列舉,結束程式。

Code

#include<iostream>
#include<cstring> 
#include<algorithm>
using namespace std;
int n,m,k,t=0;
int money=0,p[30][30];
struct hs
{
	int x,y,num;
};
bool cmp(hs x1,hs y1)
{
	return x1.num>y1.num;
}
int main()
{
	hs a[500];
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	 {
	    cin>>p[i][j];
	    if(p[i][j]!=0)
	    {
	    	t++;
	    	a[t].x=i;
	    	a[t].y=j;
	    	a[t].num=p[i][j];//記錄植株的座標以及花生數量
		}
	 }
	 sort(a+1,a+t+1,cmp);
	 for(int i=1;i<=t;i++)
	 {
	 	if(i==1)
	 	{
	 		if(a[i].x+1+a[i].x<=k)
	 		{
	 			money+=a[i].num;
	 			k=k-(a[i].x+1);
			}
			else break;
		}
		else
		{
			if(abs(a[i].x-a[i-1].x)+abs(a[i].y-a[i-1].y)+a[i].x+1<=k)//列舉每個植株
			{
				money+=a[i].num;
				k=k-(abs(a[i].x-a[i-1].x)+abs(a[i].y-a[i-1].y)+1);
			}
			else break;
		}
	 }
	cout<<money;
}

T2



這道題直接就是一個遞迴+二分,或者用雙重迴圈也可以做。但無奈我太菜了,居然沒想出來,直接打表了。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
string a,b;
char dg(int l,int r)
{
	int mid;
	char lt,rt,ans;
	if(l==r)
	{
		cout<<b[l];
		return b[l];
	}
	mid=(l+r)/2;
	lt=dg(l,mid);//二分查詢左邊
	rt=dg(mid+1,r);//二分查詢右邊
	if(rt==lt)
 	 ans=rt;
 	else ans='F';
 	cout<<ans;
 	return ans;//判斷父節點並返回
}
int main()
{
    cin>>n;
    m=1;
    for(int i=1;i<=n;i++)
     m=m*2;
    cin>>a;
    for(int i=0;i<a.size();i++)
    {
    	if(a[i]=='1') b[i+1]='I';
    	else b[i+1]='B';
	}
	dg(1,m);
	return 0;
}

T2


一看題,蒟蒻狂喜。這不就是大水題嗎?直接DFS就過掉了(正解全排列不會....)

Code

#include<iostream>
#include<cstdlib>
using namespace std;
int x,m,n,a[10005],b[10005];
bool f[10005];
void dfs(int dep)
{
	if(dep>n)
	{
		x++;
		if(x>m)//檢視是第幾大的數
		{
			for(int i=1;i<n;i++)
			 cout<<b[i]<<' ';
			cout<<b[n];
			exit(0);
	    }
	    return;
	}
	int k=1;
	if(x==0) k=a[dep];
	for(int i=k;i<=n;i++)
	 if(f[i]!=1)
	 {
	 	f[i]=1;
	 	b[dep]=i;
	 	dfs(dep+1);
	 	f[i]=0;
	 }
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	 cin>>a[i];
	dfs(1); 
}

T4



入眼一看,這不就是高精度嗎?!但仔細一看,P那麼大!肯定會超時,但無奈本蒟蒻太菜了,只能衝著部分分去了。最後的正解是高精度+快速冪。

Code

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int p,a[1010],t=0,k=0,b[1010];
void input()
{
	memset(a,0,sizeof(a));
	cin>>p;
}
void gjc()
{
	a[1000]=1;
	for(int i=1;i<=p;i++)
	{
		t=0;
		k=0;
		for(int j=1000;j>=1;j--)
		{
			k=(a[j]*2+t)/10;
			a[j]=(a[j]*2+t)%10;
			t=k;
		}
	}
}
void gjj()
{
	t=0;
	b[1000]=1;
	for(int j=1000;j>=1;j--)
	{
		if(a[j]-t-b[j]<0)
		{
			t=1;
			a[j]=a[j]*10-b[j];
		}
		else a[j]=a[j]-t-b[j];
	}
}
int main()
{
	input();
	gjc();
	gjj();
	k=0;
	for(int i=1;i<=1000;i++)
	{
		if(a[i]!=0)
		{
			k=i;
			break;
		}
	}
	cout<<1000-(k-1)<<endl;
	for(int i=501;i<=1000;i++)
	{
		cout<<a[i];
	}
	return 0;
} 

總結

總體還算不錯,但是第一題有一個細節沒考慮到,白給10分。個人感覺基礎還算紮實,但是網路流什麼的就有點拉胯了....
本人的csdn部落格


謝謝閱讀