【ブルーブリッジカップ練習】モンスタードリームファイティングウッドスティック

タイトル説明
スティックはN本ありますが、4本選びます。等辺三角形を作りたい場合、選択肢はいくつありますか?
答えはモジュロ10 ^ 9 +7です。

入力フォーマット
最初の行の整数N。
2行目のN個の整数、i番目の整数aiは、i番目の木の棒の長さを表します。

出力形式
1行の1つの整数が答えを表します。

サンプル

输入:
8
1 2 1 2 3 5 6 6
输出:
3

問題の分析と回答

简要分析:
木棍之间的关系:a=b=c+d
其实我们只需要枚举a,c即可,时间复杂度O(n^2)
注意点:
	1.我们在枚举c的时候只能枚举到a/2。因为c与d互补,c+d=d+c
	2.我们要分情况讨论c与d是否相等。因为选择一根c长度的木棍的方案数*选择一根d长度木棍的方案数≠选择两根c长度木棍的方案数
	3.排列组合。注意下是选2个还是选1个
#include <iostream>
#include <cstdio>
using namespace std;
const int mod = 1000000007;
int n;
long long p[5005],maxn,ans;
long long C2(long long x)
{
    
    
	//用于计算排列组合Cx->2(从x个值中随机取出两个,不在意顺序) 
    return x * (x - 1) / 2;
}

int main()
{
    
    
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
    
    
        long long t;
        scanf("%lld", &t);
        maxn = max(maxn, t);
        //我们保存的是某一数值出现的次数,而不是单纯的保存数值。(此方式在很多地方都可以用,强烈推荐) 
        p[t]++;
    }
    //a=b=c+d从而构成等边三角形,我们在这里枚举a和c 
    for (int a = 1; a <= maxn; a++)
        //c最大取到a/2,因为c+d=d+c;如果取到a,会导致重复 
        for (int c = 1; c <= a/2; c++)
        {
    
    
        //取到d的值 
        int d = a - c;
        //如果d和c不相等的话,我们取选择一根c木棍的方案数乘以选择一根d木棍的方案数 
        if (d != c)
        {
    
    
            if (p[a] >= 2 && p[d] >= 1 && p[c] >= 1)
            	//从值为a的里面选两个,值为c的里面选一个 ,值为d的里面选一个 
                ans += (C2(p[a])*(p[c] % mod)) % mod*(p[d] % mod) % mod;
        }
        else
        //如果d和c相等的话,我们取选择两根c木棍的方案数 
        {
    
    
            if (p[a] >= 2 && p[c] >= 2)
            	//从值为a的里面选两个,值为c的里面选两个 
                ans += C2(p[a])*C2(p[c]) % mod;
        }
        ans %= mod;
        }
    printf("%lld\n", ans % mod);
    return 0;
}
附赠:
laji写法
时间复杂度:O(n^4)
只能运行数据很小的情况
不用谢不用谢~~~
溜了溜了。。。
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=1000000007;
int n;
int a[100005];
long long ans;
int main(){
    
    
	cin>>n;
	for(int i=0;i<n;i++){
    
    
		cin>>a[i];
	}
	for(int i=0;i<n-3;i++){
    
    
		for(int j=i+1;j<n-2;j++){
    
    
			for(int k=j+1;k<n-1;k++){
    
    
				for(int m=k+1;m<n;m++){
    
    
					int sum=a[i]+a[j]+a[k]+a[m];
					if(sum%3==0){
    
    
						int avg=sum/3;
						int cnt=1;
						if(a[i]==avg) cnt++;
						if(a[j]==avg) cnt++;
						if(a[k]==avg) cnt++;
						if(a[m]==avg) cnt++;
						if(cnt==3){
    
    
							ans++;
						}
					}
				}
			}
		}
	}
	cout<<ans%mod<<endl;
	return 0;
}

おすすめ

転載: blog.csdn.net/kieson_uabc/article/details/108110982