洛谷 - 一些好玩的问题

目录

P2181 对角线 - 数学

P1009 [NOIP1998 普及组] 阶乘之和 - 越界

P1217 [USACO1.5]回文质数 Prime Palindromes - 超时

P5729 【深基5.例7】工艺品制作 - 三维数组


P2181 对角线 - 数学

对于一个 n 个顶点的凸多边形,它的任何三条对角线都不会交于一点。请求出图形中对角线交点的个数。

例如,6 边形:

洛谷 - 一些好玩的问题_第1张图片

输入格式

输入只有一行一个整数 n,代表边数。

输出格式

输出一行一个整数代表答案。

直接背公式:n * (n-1) * (n-2) * (n-3) / 4!

同时为了防止爆掉,但又不想写高精,

我们可以采用一种化简的技巧

于是原式可以化为:

n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4

#include
using namespace std;
unsigned long long n,ans;
int main()
{
    scanf("%lld",&n);
    ans=n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4;
    printf("%lld\n",ans);
    return 0;
}

P1009 [NOIP1998 普及组] 阶乘之和 - 越界

洛谷 - 一些好玩的问题_第2张图片

 正常做法:高精度

#include
#include
using namespace std;
int n,a[101]={0},s[101]={0};
void change(int x)
{
	int g=0;
	for(int i=100;i>=0;i--)
	{
		a[i]=a[i]*x+g;
		g=a[i]/10;
		a[i]=a[i]%10;
	}
}
void qh()
{
	int g=0;
	for(int i=100;i>=0;i--)
	{
		s[i]=s[i]+a[i]+g;
		g=s[i]/10;
		s[i]=s[i]%10;
	}
}
void sc()
{
	int w;
	for(int i=0;i<=100;i++)
	{
		if(s[i]!=0)
		{
			w=i;
			break;
		}
	}
	for(int i=w;i<=100;i++)
	   printf("%d",s[i]);
}
int main()
{
	scanf("%d",&n);
	s[100]=a[100]=1;
	for(int i=2;i<=n;i++)
	{
		change(i);
		qh();
	}
	sc();
	return 0;
}

 遇到高精度直接python走起

打表

具体思路

先用python打表,然后以字符串形式存入c++代码中

实现

python代码

f=open(r'point.txt','w') #存入文件
sum=1
i=2
last=1
n=int(input())
while i<=n:
	last*=i
	sum+=last
	i+=1				 #主函数
	f.write('"')		 #上引号
	f.write(str(sum))	#具体值
	f.write('",')		#下引号与逗号
f.close				  #关闭文件写入

存入cpp后代码

#include
using namespace std;
string a[60]={"0","1","3","9","33","153","873","5913","46233","409113","4037913","43954713","522956313","6749977113","93928268313","1401602636313","22324392524313","378011820620313","6780385526348313","128425485935180313","2561327494111820313","53652269665821260313","1177652997443428940313","27029669736328405580313","647478071469567844940313","16158688114800553828940313","419450149241406189412940313","11308319599659758350180940313","316196664211373618851684940313","9157958657951075573395300940313","274410818470142134209703780940313","8497249472648064951935266660940313","271628086406341595119153278820940313","8954945705218228090637347680100940313","304187744744822368938255957323620940313","10637335711130967298604907294846820940313","382630662501032184766604355445682020940313","14146383753727377231082583937026584420940313","537169001220328488991089808037100875620940313","20935051082417771847631371547939998232420940313","836850334330315506193242641144055892504420940313","34289376947494122614363304694584807557656420940313","1439295494700374021157505910939096377494040420940313","61854558558074209658512637979453093884758552420940313","2720126133346522977702138448994068984204397080420940313","122342346998826717539665299944651784048588130840420940313","5624964506810915667389970728744906677010239883800420940313","264248206017979096310354325882356886646207872272920420940313","12678163798554051767172643373255731925167694226950680420940313","620960027832821612639424806694551108812720525606160920420940313","31035053229546199656252032972759319953190362094566672920420940313"};
int main()
{
	int n;
	cin>>n;
	cout<

P1217 [USACO1.5]回文质数 Prime Palindromes - 超时

洛谷 - 一些好玩的问题_第3张图片

 看起来很简单,但我赌你不可能一遍AC

#include
#include
#include
#include
#include
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;

int zs(int n)
{
	if(n<2) return 0;
	for(int i=2;i<=sqrt(n);i++)
		if(n%i==0) return 0;
	return 1;
}

int hw(int n)
{
	int sum=0;
	int k=n;
	while(n)
	{
		sum=sum*10+n%10;
		n/=10;
	}
	if(sum==k) return 1;
	else return 0; 
}

int main()
{
	int n,m;
	cin>>n>>m;
	for(int j=n;j<=m;j++)
	{
		if(j==9989900)  //打表找到最大质数9989899
		break;
		if(hw(j)&&zs(j))    //先判回文,超时1个点
        //if(zs(j)&&hw(j))   先判断质数再判断回文,直接超时3个点
		printf("%d\n",j);
	}
	return 0;
}



 超时总结:

1、将 cin 改为 scanf ,cout 改为 printf (当数据大于1e7时快十多倍)

2、将特殊的先判断(循环判断顺序由特殊到一般)

3、利用打表法观察数的边界,强行剪枝

4、超时绝大多数情况出在循环

P5729 【深基5.例7】工艺品制作 - 三维数组

洛谷 - 一些好玩的问题_第4张图片

 好像三维数组比较少见...

首先由于是立方体,那么肯定要构造立方体的模型,也就是三维数组,然后总的大体积就是长宽高相乘,也就是wxh,然后看了半天题目也看不懂是怎么减去的,但根据题目的分析可得(1,1,1) (2,2,2)刚好减去了8的体积,那么就可以姑且认为这是减去的是三维排列
例如:(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)刚好为八个,如果这样理解的话,这题就清晰了;
 

#include
#include
#include
#include
#include
typedef long long LL;
const int N=1e5+10;
using namespace std;
//int a[N][N][N];  三维数组就是不能这样定义,不知道为什么 
int a[21][21][21];
int w, x, h, q;
int x1, z1, x2, y2, z2,sum ;
int y1;
int main() {
	int y1;	//只能在局部取名y1 
	cin >> w >> x >> h;
	cin >> q;
	for (int i = 0; i < q; i++)//循环n趟
	{
		cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
		for (int i = x1; i <= x2; i++)
		{
			for (int j = y1; j <= y2; j++)
			{
				for (int k = z1; k <= z2; k++)
				{
					a[i][j][k] = 1;
				}
			}
		}
	}
	for (int i = 1; i <= w; i++)
	{
		for (int j = 1; j <= x; j++)
		{
			for (int k = 1; k <= h; k++)
			{
				if (a[i][j][k] == 0)
					sum++;
			}
		}
	}
	cout << sum << endl;
	return 0;
}

我就不理解那些题解为啥这么花里胡哨的... 

离奇事件:

1、c++中不能在全局取名y1(????为什么为什么??)

2、可能是有的编译器不支持const int N=1e5+10;   int a[N][N][N]; 这样的操作

(有懂的大佬快来评论)

你可能感兴趣的:(洛谷,蓝桥杯,算法,c++,c语言,c#)