小陈的开学第十周程序

本文记录了小陈在编程竞赛中遇到的挑战与解题思路,涉及Atcoder、codeforces、牛客网-四川大学新生赛和PTA等多个平台的题目。在Atcoder中,通过数学方法解决了平均路径长度问题;codeforces中探讨了如何使两名学生间距离最大化;在牛客网的比赛中,实现了最长公共子串查找和判断胡牌的算法。此外,还讨论了其他平台的题目,如欧拉筛、后缀自动机等,分享了解题过程与代码实现。
摘要由CSDN通过智能技术生成

一、Atcoder

1.Average Length

题意

There are N towns in a coordinate plane. Town i is located at coordinates (xi, yi). The distancebetween Town i and Town j is √(xi−xj)^2+(yi−yj) ^2.

There are N! possible paths to visit all of these towns once. Let the length of a path be the distance covered when we start at the first town in the path, visit the second, third, …, towns, and arrive at the last town (assume that we travel in a straight line from a town to another). Compute the average length of these N! paths.

2≤N≤8
−1000≤xi≤1000
−1000≤yi≤1000
(xi,yi)≠(xj,yj) (if i≠j)
(Added 21:12 JST) All values in input are integers.

输入

Input is given from Standard Input in the following format:

N
x1 y1
:
xN yN

输出

Print the average length of the paths. Your output will be judges as correct when the absolute difference from the judge’s output is at most 10^−6.

样例输入1

3
0 0
1 0
0 1

样例输出1

2.2761423749

There are six paths to visit the towns: 1 → 2 → 3, 1 → 3 → 2, 2 → 1 → 3, 2 → 3 → 1, 3 → 1 → 2, and 3 → 2 → 1.
The length of the path 1 → 2 → 3 is √(0−1)^2+(0−0) ^2+√(1−0) 2+(0−1) ^2=1+√2.
By calculating the lengths of the other paths in this way, we see that the average length of all routes is:
((1+√2)+(1+√2)+(2)+(1+√2)+(2)+(1+√2))/6=2.276142…

样例输入2

2
-879 981
-866 890

样例输出2

91.9238815543

样例输入3

8
-406 10
512 859
494 362
-955 -475
128 553
-986 -885
763 77
449 310

样例输出3

7641.9817824387

解题思路

这题看上去就知道要用DFS,但是我用DFS无从下手,我就用了数学方法,找到了他们之间的规律,但是我改代码改了好久,最后终于过了。其实就是每两个点之间的距离的次数是有一定规律的,把次数算出来,然后算一次距离,然后乘上次数就可以了。
后来我又去找了一个用DFS写的代码,学习一下。

程序代码:(My-AC)

#include<bits/stdc++.h>
using namespace std;
const int N=10;
struct node{
   
	int x,y;
}a[N];
double num[N][N];
double ans=0;
int n;
int nn[]={
   0,0,2,4,12,48,240,1440,10080};
int f(int n){
   
	int t=1;
	for(int i=1;i<=n;i++){
   
		t=t*i;
	}
	return t;
}
//int f1(int n){
   
//	if(n==2){
   
//		return 1;
//	}
//	return n*(n-1)/f(n-2);
//}
int main(){
   
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
   
		scanf("%d %d",&a[i].x,&a[i].y);
	}
//	int len=f(n)*(n-1)/f1(n);
	for(int i=1;i<=n;i++){
   
		for(int j=i+1;j<=n;j++){
   
			num[i][j]=sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));
			ans+=(num[i][j]*nn[n]);
		}
	}
	printf("%.10f\n",ans/f(n));
	return 0;
}

程序代码:(DFS-AC)

#include"bits/stdc++.h"
using namespace std;
struct point{
   
	double x,y;
}p[10000];
double n;
int num=0;
double ans=0;
int a[10],flag[10];
void dfs(int now){
   
    if(now==n){
   
    	num++;
        for(int i=0;i<n-1;i++){
   
        	//cout<<"    "<<a[i];
        	//cout<<sqrt((double)(p[a[i]].x-p[a[i]+1].x)*(p[a[i]].x-p[a[i]+1].x)+(double)(p[a[i]].y-p[a[i]+1].y)*(p[a[i]].y-p[a[i]+1].y))<<endl;
            ans+=(double)sqrt((double)(p[a[i]].x-p[a[i+1]].x)*(p[a[i]].x-p[a[i+1]].x)+(double)(p[a[i]].y-p[a[i+1]].y)*(p[a[i]].y-p[a[i+1]].y));
        }
        return;
    }
    for(int i=1;i<=n;i++){
   
        if(flag[i]==0){
   
            flag[i]=1;
            a[now]=i;
            dfs(now+1);
            flag[i]=0;
        }
    }
}
int main(){
   
	cin>>n;
	for(int i=1;i<=n;i++){
   
		scanf("%lf%lf",&p[i].x,&p[i].y);
	}
	dfs(0);
	printf("%.10f",ans/num);
	return 0;
} 

2.Knight

题意

There is a knight - the chess piece - at the origin (0,0) of a two-dimensional grid.
When the knight is at the square (i,j), it can be moved to either (i+1,j+2) or (i+2,j+1).
In how many ways can the knight reach the square (X,Y)?

Find the number of ways modulo 10^9+7.

1≤X≤10^6
1≤Y≤10^6
All values in input are integers.

输入

Input is given from Standard Input in the following format:

X Y

输出

Print the number of ways for the knight to reach (X,Y) from (0,0), modulo 10^9+7.

样例输入1

3 3

样例输出1

2

There are two ways: (0,0)→(1,2)→(3,3) and (0,0)→(2,1)→(3,3).

样例输入2

2 2

样例输出2

0

The knight cannot reach (2,2).

样例输入3

999999 999999

样例输出3

151840682

Print the number of ways modulo 10^9+7.

解题思路

其实这道题我没有写,当时写完第三题,时间就差不多快结束了,就没写这道题了。
以下是我找的别人写的代码。

程序代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const int p = 1e9 + 7;
int f[maxn+10];
void init(){
   
    f[0]=1;
    for(int i=1;i<=maxn;i++){
   
        f[i]=(long long)f[i-1]*i%p;
    }
}

int fast(int a,int n){
   
    if(n==0)return 1;
    if(n%2)return (long long)a*fast(a,n-1)%p;
    int tmp=fast(a,n/2);
    return (long long)tmp*tmp%p;
}

int C(int n,int m){
   
    if(n==m||m==0)return 1;
    return ((long long)f[n]*fast(f[m],p-2)%p)*fast(f[n-m],p-2)%p;
}

int main() {
   
	int x,y;
	scanf("%d%d",&x,&y);
	int t1 = (2*y-x);	
	int t2 = (2*x-y);
	if(t1 % 3 != 0 || t2 %3 != 0 || t1 < 0 || t2 < 0){
   
		printf("0\n");
	}
	else{
   
		init();
		t1 = t1/3;
		t2 = t2/3;
		printf("%d\n",C(t1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值