1. 程式人生 > 實用技巧 >2020ICPC·小米 網路選拔賽第一場

2020ICPC·小米 網路選拔賽第一場

2020ICPC·小米 網路選拔賽第一場

比賽分析

這場高手真的還是挺多的。我們隊伍也實在是太拉垮了,有個隊友實驗未歸。

我上來切了C、I 然後就沒有過題了。

首先是J題,我的鍋。我就想了幾分鐘就感覺是二維線段樹,就直接開始寫了,浪費快2hrs+,後來我突然發現我的複雜度少乘了個log,血虧。

隊友的A也調了很久,一直沒有過,據他所說,他被卡傻了。

隊友2終於實驗回來,做了個D,正解應該是邊雙還是啥的,反正他寫個什麼割點啥的。

總結

這場反正也進不了,但是暴露的問題非常多

第一,各自蠻幹非常明顯,交流少了。 有想法應該先和隊友交流一下,尤其是這種網路賽,多執行緒可敲的時候,反而不要忽視單機子的這個重要流程。像我的二維線段樹,如果講清楚,隊友,或者我自己都可能看到問題,簡單的dp就不會做成資料結構題

第二,題意方面。每個人優先讀一道題,然後翻譯成中文,再讓隊友帶著中文去再讀一遍題意,檢查是否理解錯誤。比如I題,我一開始讀錯了,隊友準備寫的時候,提醒了一下我,我才發現錯誤。以後要保證每道題目至少要被反覆讀過兩遍。

第三,要注意看榜單資訊。如果有些題很多隊過了,或者說,一些題很快被切了,那麼它極大概率不是比較複雜的資料結構題,以及難的數論。。。

第四,是勤換思路。有些時候想題目不要侷限於一種演算法中,要果敢放棄。思路或者題目什麼時候該進行捨棄嘞?

如果思路想不通到15min,並且此題可做,那麼換思路

如果某個題花費30min思考沒有突破,先放下,去讀題

C 簡單簽到

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
#define max(a,b) (a>b ? a:b)
#define min(a,b) (a<b ? a:b)
#define swap(a,b) (a^=b^=a^=b)
#define maxn 105
#define minn -105
#define ll long long int
#define ull unsigned long long int
#define uint unsigned int
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'|ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
int main()
{
    string s;
    cin>>s;
    int ans=0;
    int len=s.size();
    for(int i=0;i<len;i++)
    {
        if(s[i]=='w')ans++;
        if(i)
        {
            if((s[i]=='w')&&(s[i-1]=='w'))ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}


I dfs 記憶化

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define max(a,b) (a>b ? a:b)
#define min(a,b) (a<b ? a:b)
#define swap(a,b) (a^=b^=a^=b)
#define maxn 1405
#define minn -105
#define ll long long int
#define ull unsigned long long int
#define uint unsigned int
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'|ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
int n,m;


char a[maxn][maxn];
bool been[maxn][maxn];
int out[maxn][maxn];

bool dfs(int x,int y)
{
    if(x==0||y==0||x==n+1||y==m+1)
    {
        return 1;
    }
    if(been[x][y])
    {
        return out[x][y];
    }
    been[x][y]=1;
    bool cur=0;
    if(a[x][y]=='W')cur=dfs(x-1,y);
    if(a[x][y]=='A')cur=dfs(x,y-1);
    if(a[x][y]=='S')cur=dfs(x+1,y);
    if(a[x][y]=='D')cur=dfs(x,y+1);
    out[x][y]=cur;
    return cur;

}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(!been[i][j])
            {
                dfs(i,j);
            }
            if(out[i][j]==1)ans++;

        }


    cout<<ans<<endl;
    return 0;
}

J dp

維護二維字首和就好了,沒必要實現每次區間的維護。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define max(a,b) (a>b ? a:b)
#define min(a,b) (a<b ? a:b)
#define swap(a,b) (a^=b^=a^=b)
#define maxn 1305
#define minn -105
#define ll long long int
#define ull unsigned long long int
#define uint unsigned int
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'|ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
int a[maxn][maxn];
int pre[maxn][maxn];
int give[maxn][maxn];
int n,m,x,y;
string ac="^_^\n";
string wa="QAQ\n";
void solve()
{
    cin>>n>>m>>x>>y;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            a[i][j]=read();

        }
    int cur=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            //give[i][j]=0;
            int cur=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
            pre[i][j]=cur;
            cur+=pre[max(0,i-x)][max(0,j-y)]-pre[i][max(0,j-y)]-pre[max(0,i-x)][j];
            if(i>=n+2-x||j>=m+2-y)
            {
                if(a[i][j]!=cur)
                {
                    cout<<wa;
                    return;
                }
                continue;
            }
            else
            {
                if(cur>a[i][j])
                {
                    cout<<wa;
                    return;
                }
                pre[i][j]+=a[i][j]-cur;
            }
        }
    cout<<ac;

}
int main()
{
    int _t;
    cin>>_t;
    while(_t--)solve();
    return 0;
}

D

#include<bits/stdc++.h>
using namespace std;
struct tedge{
	int w,next;
}e[1000010];
int l[500010],dfn[500010],low[500010],st[500010],del[500010],gu[500010],d[500010];
int cnt,tot,top,cnt1,n,m,root,sum;
vector <int> ve[500010];
void add(int x,int y)
{
	e[++cnt].w=y;
	e[cnt].next=l[x];
	l[x]=cnt;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++tot;
	st[++top]=x;
	if(x==root&&l[x]==0)
	{
		ve[++cnt1].push_back(x);
		gu[x]=1;
		return;
	}
	for(int i=l[x];i;i=e[i].next)
	{
		int v=e[i].w;
		if(!dfn[v])
		{
			tarjan(v);
			low[x]=min(low[x],low[v]);
			if(low[v]>=dfn[x])
			{
				cnt1++;
				int z;
				do{
					z=st[top--];
					ve[cnt1].push_back(z);
				}while(z!=v);
				ve[cnt1].push_back(x);
			}
		}
		else
		low[x]=min(low[x],dfn[v]);
	}	
}
int main()
{
	cin>>n>>m;
	int x,y;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		if(x==y)
		continue;
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;i++)
	if(!dfn[i])
	{
		sum++;
		root=i;
		tarjan(i);
	}
	for(int i=1;i<=cnt1;i++)
    for(int j=0; j<ve[i].size();j++)
    d[ve[i][j]]++;
    for(int i=1;i<=n;i++)
    {
    	if(gu[i])
    	cout<<sum-1<<" ";
    	else
    	cout<<sum-1+d[i]<<" ";
	}
    return 0;
}

A

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int a[300010],n,m,x;
int f[10000010],bj[10000010],prime[10000100],tot,f1[10000010]; 
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		f1[a[i]]++;
		f[a[i]]++;
	}
	sort(a+1,a+n+1);
	int maxn=a[n];
	int ans=0;
	for(int j=2;j<=maxn;j++)
	{
		if(!bj[j]){
			prime[++tot]=j;f[j]+=f[1];
		}
		for(int i=1;i<=tot;i++)
		{
			if(j*prime[i]<=maxn)
			{
				bj[j*prime[i]]=1;
				f[j*prime[i]]=max(f[j*prime[i]],f1[j*prime[i]]+max(f[j],f[prime[i]]));
			}
			else break;
		}
		ans=max(ans,f[j]);
	}
	cout<<ans;
	return 0;
}