Educational Codeforces Round 157 (Rated for Div. 2) 复盘

又是vp的稀烂的一场。

A没问题。被B一道800卡了。

但是确实非常简单,就是从式子上入手,让\(|x_1-x_2|+|y_1-y_2|\)最小就可以了。
所以就把两维度分开来看,这两维之间的距离是不会影响代价的,这是曼哈顿距离的特点。
那么就很明显了,就是从中间分开。

但是我vp的时候并没有看出来。而是在猜结论。因为我不知道怎么想,但是事实上我就应该直接分析我的答案是什么样的,然后得出结论。我没有去思考,这非常不好。这题我感觉就是这样的。我其实可以适当的跳过一些证明,猜一些小结论。比如这题,我开始的时候就被分成两组这个东西给拉扯住了,没有往下想的思路了。很要命,但是事实上这个根本就不是什么很难的东西。以后看题可以跟注重从结果出发来分析题目。

然后就是C,更是依托。赛时写了160行。只能说我的代码能力是更强了,这种事都干得出来。。。
然而cf的c题根本就不会让你写这么多。我其实就没有仔细分析题目就去写了。
我应该去思考一下,另一半到底应该满足写什么条件,然后在根据这条件去维护一些东西。

很明显,满足的条件就是1.长度 2.数值和。如果我知道了另一半所需要用的长度,那么,那一边的数值和也就知道了。
那这不就很好维护吗?直接用一个数组就可以了。然后我就把5个情况全部分开。。写傻了。。然后还wa了,都不知道错哪里了。

好了,现在知道了。160行写错了一行,就死了。
服了,但凡做法简单点。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
	char c=getchar();ll a=0,b=1;
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
ll n;
string s[200001];
ll f[351][351];
ll count(string a,ll x)
{
	ll ans=0;
	for(ll i=0;i<x;i++)ans+=a[i]-'0';
	return ans;
	
}
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("2.out","w",stdout);
//	ll T=read();
//	while(T--)
	{
		n=read();
		for(ll i=1;i<=n;i++)
		{
			cin>>s[i];
//			cout<<count(s[i],s[i].size())<<endl;
		}
		memset(f,0,sizeof(f));
		ll ans=0;
		for(ll i=1;i<=n;i++)
		{
			if(s[i].size()==2)
			{
				f[count(s[i],2)][0]++;
			}
			else
			if(s[i].size()==4)
			{
				if(count(s[i],4)-count(s[i],1)>0)
				f[count(s[i],1)][count(s[i],4)-count(s[i],1)]++;
				f[0][count(s[i],4)]++;
			}
		}
		for(ll i=1;i<=n;i++)
		{
			if(s[i].size()==2)
			{
				ans+=f[count(s[i],2)][0];
				for(ll j=1;j<=9;j++)
				{
					ans+=f[j][count(s[i],2)+j];
				}
			}
			if(s[i].size()==4)
			{
				ll forth=count(s[i],4)-count(s[i],3);
				if(count(s[i],3)-forth>0)ans+=f[count(s[i],3)-forth][0];//2
				ans+=f[0][count(s[i],4)];
			}
		}
		memset(f,0,sizeof(f));
		for(ll i=1;i<=n;i++)//1
		{
			if(s[i].size()==1)
			{
				f[count(s[i],1)][0]++;
			}
			if(s[i].size()==3)
			{
				if(count(s[i],3)-count(s[i],1)>0)f[count(s[i],1)][count(s[i],3)-count(s[i],1)]++;
			}
			if(s[i].size()==5)
			{
				if(count(s[i],5)-count(s[i],2)>0)f[count(s[i],2)+50][count(s[i],5)-count(s[i],2)]++;
			}
		}
		for(ll i=1;i<=n;i++)
		{
			if(s[i].size()==1)
			{
				ans+=f[count(s[i],1)][0];
				for(ll k=1;k<=9;k++)
				{
					ans+=f[k][k+count(s[i],1)];
				}
				for(ll j=2;j<=18;j++)
				{
					ans+=f[j+50][j+count(s[i],1)];
				}
			}
		}
//		cout<<ans<<endl;
		memset(f,0,sizeof(f));
		for(ll i=1;i<=n;i++)//3
		{
			if(s[i].size()==1)
			{
				f[count(s[i],1)][0]++;
			}
			if(s[i].size()==3)
			{
				f[0][count(s[i],3)]++;
			}
			if(s[i].size()==5)
			{
				if(count(s[i],5)-count(s[i],1)>0)
				f[count(s[i],1)][count(s[i],5)-count(s[i],1)]++;
			}
		}
		for(ll i=1;i<=n;i++)
		{
			if(s[i].size()==3)
			{
				ll last1=count(s[i],3)-count(s[i],2);
				ans+=f[0][count(s[i],3)];// 3
//				cout<<ans<<endl;
				if(count(s[i],2)-last1>0)
				ans+=f[count(s[i],2)-last1][0];// 1
//				cout<<ans<<endl;
				for(ll j=1;j<=9;j++)
				{
					ans+=f[j][count(s[i],3)+j];// 5
				}
//				cout<<ans<<endl;
			}
		}
//		cout<<ans<<endl;
		memset(f,0,sizeof(f));
		for(ll i=1;i<=n;i++)//5
		{
			if(s[i].size()==1)
			{
				f[count(s[i],1)][1]++;
			}
			if(s[i].size()==3)
			{
				f[count(s[i],3)][3]++;
			}
			if(s[i].size()==5)
			{
				f[count(s[i],5)][5]++;
			}
		}
		for(ll i=1;i<=n;i++)
		{
			if(s[i].size()==5)
			{
				ll last2=count(s[i],5)-count(s[i],3);
				if(count(s[i],3)-last2>0)ans+=f[count(s[i],3)-last2][1];
				ll last1=count(s[i],5)-count(s[i],4);
				if(count(s[i],4)-last1>0)ans+=f[count(s[i],4)-last1][3];
				ans+=f[count(s[i],5)][5];
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
/*

2 
2 942 

*/
posted @ 2024-04-17 20:25  HL_ZZP  阅读(4)  评论(0编辑  收藏  举报