1. 程式人生 > 實用技巧 >2020杭電多校第一場(待更新)

2020杭電多校第一場(待更新)

2020杭電多校第一場

難度真的是一言難盡……

目錄

1004.Distinct Sub-palindromes


題意:

要求構建一個長度為n的字串,求該字串中迴文子串的數量最少有多少種情況。

首先畫一下n比較小的情況,發現當n<4時無論怎樣構建,其迴文子串的數量都是一樣的,那麼情況數量就是26^n;而當n=4時,我們嘗試由n=3的情況變化過來,n=3時,有aab、aaa、aba、abc,現在在這幾個串後新增字母,aab、aaa、aba無論怎麼新增都會導致迴文子串增加,而abc變成abca後迴文子串數量不變,以此類推當n>3時,可以構建為abcabca……,這樣情況數就為26x25x24。

程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
ll m=998244353;
ll fpow(ll a,ll b)
{
    if(!b)
    {
        return 0;
    }
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=(ans*a)%m;
        }
        a=(a*a)%m;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll n;
    int t;
    cin>>t;
    while(t--)
    {
    	cin>>n;
    	if(n>3)
    	{
    		cout<<26*25*24<<endl;
		}
		else
		{
			cout<<fpow(26,n)<<endl;
		}
	}
    return 0;
}

1006.Leading Robots


題意:

給定n個機器人,每個機器人都有自己的位置p和加速度a,問當時間無限下去後,有多少機器人移動到最前面過。

看著就很像一個單調棧,但當時覺得“n^2還過不了5w嗎?”,反手就是一個暴力,果斷GG。

首先我們考慮什麼情況下某個機器人會移動到最前面,很顯然,加速度最大的肯定可以,而且還是最後移動到的,而位置最前的一定是最先的;如果一個機器人的加速度大於它前面的機器人,那麼它肯定可以超過前面的,而要達到最前端,就需要每個機器人都能超過前面的機器人,這樣一條鏈就形成了。

為了維護這麼一個單調棧,我們先預處理一下資料,將機器人以加速度為主位置為輔排序,然後依次將機器人放入棧中,棧頂元素每次與待加入元素比較,如果棧頂元素不能超過待加入元素,那麼很明顯要踢掉,而棧頂元素超過其前面的那個機器人的時間大於待加入機器人超過棧頂的時間那麼也不滿足,踢掉。

程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
using namespace std;
struct robot
{
	long long p,a;
}ro[50005];
bool cmp(robot a,robot b)
{
	if(a.a == b.a)
	{
		return a.p<b.p;
	}
	return a.a<b.a;
}
bool check(robot a,robot b,robot c)
{
	return (b.p-a.p)*(b.a-c.a)>=(c.p-b.p)*(a.a-b.a);
}
map<pair<long long,long long>,int> mp;
int stack[50005];
int top;
int n;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		mp.erase(mp.begin(),mp.end());
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d",&ro[i].p,&ro[i].a);
			mp[make_pair(ro[i].p,ro[i].a)]++;
		}
		sort(ro+1,ro+n+1,cmp);
		top=0;
		for(int i=1;i<=n;i++)
		{
			while(top)
			{
				if(ro[stack[top]].p<=ro[i].p)
				{
					top--;
				}
				else if(top>1 && check(ro[stack[top-1]],ro[stack[top]],ro[i]))
				{
					top--;
				}
				else
				{
					break;
				}
			}
			stack[++top]=i;
		}
		int ans=top;
		for(int i=1;i<=top;i++)
		{
			if(mp[make_pair(ro[stack[i]].p,ro[stack[i]].a)]>1)
			{
				ans--;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

部落格地址