HPU 第三次积分赛:阶乘之和(水题)

阶乘之和

描述

对于整数pp,给出以下定义
p=x_{1}!+x_{2}!+x_{3}!+...+x_{q}!(x_{i}<x_{j}for\ all\ i<j )p=x1​!+x2​!+x3​!+...+xq​!(xi​<xj​for all i<j)且x_{i} \neq 0xi​≠0
((注释:p等于多个数的阶乘和,并且x_{1},x_{2},x_{3},...,x_{q}x1​,x2​,x3​,...,xq​为不相等的任意正整数,即组成p的阶乘不重复使用))
给定两个整数x,y,判断二者是否能满足以上定义。若二者都满足定义,设x由k_{1}k1​个数的阶乘和组成,y由k_{2}k2​个数的阶乘和组成,若k_{1}=k_{2}k1​=k2​,按下述输出格式输出二者的定义形式((输出时,阶乘按递增形式输出,例如:7=1!+3!))。

输入

第一行输入一个整数T,代表T组测试数据。(1\leq T \leq 10000)(1≤T≤10000)
接下来T行,每行包含两个整数x,y。(1\leq x,y \leq 10^{18})(1≤x,y≤1018)

输出

对于每组x,y输出包含两部分:
①如果二者都满足以上定义,输出“SEYES”;如果只有其一满足以上定义,输出“YNEOS”;如果二者都不满足以上定义,则输出“ONO”。
②当x,y都满足以上定义且k_{1}=k_{2}k1​=k2​时,输出二者的定义形式。否者输出“dWvWb”。

输入样例 1 

4
7 7
1 2
4 2
4 4

输出样例 1

Case 1:SEYES
7=1!+3!
7=1!+3!
Case 2:SEYES
1=1!
2=2!
Case 3:YNEOS
dWvWb
Case 4:ONO
dWvWb

一道水题。一开始受Codeup 1085这道题的影响,一直从正向考虑,导致没有准确的思路。然后用了dfs,果断超时,加了剪枝之后时间并没有降下来QAQ,最后看了一下别人提交的代码,好短的代码长度,好快的运行时间QAQ。果断放弃之前的思路,从逆向考虑,马虎了一次后第二次就过了。

没想到这个题能卡三个小时,WA6发,果然前期太猛后期就萎了

AC代码

#include <bits/stdc++.h>
#define ll long long
#define ms(a) memset(a,0,sizeof(a));
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e6+10;
const double E=exp(1);
ll a[maxn];
int b[maxn];
int c[maxn];
int vis[maxn];
int vis1[maxn];
int main(int argc, char const *argv[])
{
	ios::sync_with_stdio(false);
	a[1]=1;
	// 打表记录阶乘
	for(int i=2;i<=20;i++)
		a[i]=a[i-1]*i;
	int t;
	int xx=0;
	cin>>t;
	ll x,y;
	while(t--)
	{
		cin>>x>>y;
		ll X=x;
		ll Y=y;
		int flag1=0,flag2=0;
		int o1=0;
		int o2=0;
		ms(vis);
		while(X)
		{
			for(int i=20;i>=1;i--)
			{
				if(X>=a[i])
				{
					b[o1++]=i;
					vis[i]++;
				}
				if(X==0)
				{
					flag1=1;
					break;
				}
			}
		}
		while(Y)
		{
			for(int i=20;i>=1;i--)
			{
				if(Y>=a[i])
				{
					vis1[i]++;
					c[o2++]=i;
				}
				if(Y==0)
					flag2=1;
			}
		}
		sort(b,b+o1);
		sort(c,c+o2);
		int O1=o1,O2=o2;
		// 去一下重吧,不知道为什么不去重会有重复元素
		o1=unique(b,b+o1)-b;
		o2=unique(c,c+o2)-c;
		if(o1!=O1)
			flag1=0;
		if(o2!=O2)
			flag2=0;
		cout<<"Case "<<++xx<<":";
		if(flag1+flag2==0)
			cout<<"ONO\n"<<"dWvWb"<<endl;
		if(flag1+flag2==2)
		{
			cout<<"SEYES"<<endl;
			if(o1!=o2)
				cout<<"dWvWb"<<endl;
			else
			{
				cout<<x<<"=";
				for(int i=0;i<o1;i++)
				{
					if(i)
						cout<<"+";
					cout<<b[i]<<"!";
				}
				cout<<endl;
				cout<<y<<"=";
				for(int i=0;i<o2;i++)
				{
					if(i)
						cout<<"+";
					cout<<c[i]<<"!";
				}
				cout<<endl;
			}
		}
		if(flag2+flag1==1)
			cout<<"YNEOS\n"<<"dWvWb"<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wang_123_zy/article/details/81456419