UVA11554 Hapless Hedonism 题解
注:本题与 UVA11401 Triangle counting 一模一样。因此题解大致相似。
UVA也有原题?
简要题意:
若干组数据,每组数据给出一个 \(n\) ,求出 三边均 \(\leq n\) 且互不相等 的三角形个数。两个三角形不同当且仅当至少有一边长度不同。
首先我们应当考虑三角形的性质。设三边为 \(x,y,z\) 且 \(x>y>z\).
则:
\[x < y+z
\]
可以得到 \(y\) 的范围:
\[x-z < y < x
\]
假设 \(f_x\) 表示 \(x\) 为最长边时的答案。
此时应存在:
\[f_x = x - (x-z) - 1 = z - 1
\]
显然这是已知 \(z\) 的情况。\(z \leq x-2\),所以:
\[f_x = \sum_{z=1}^{x-2} z-1 = \sum_{z=1}^{x-1} z = \frac{(x-1)(x-2)}{2}
\]
但是你会发现这并不正确。\(y=z\) 的情况需要剔除,这是一个简单的容斥思想。
当 \(y=z\) 时,显然存在:
\[\frac{x}{2} + 1 \leq y = z \leq x-1
\]
所以这种情况的方案数为:
\[(x-1) - (\frac{x}{2} + 1) = \frac{x-2}{2}
\]
考虑原来可能把 \(y=2 , z = x-1\) 和 \(y=x-1 , z=2\) 重复计算,因此可得:
\[f_x = \frac{ \frac{(x-1)(x-2)}{2} - \frac{x-2}{2} }{2} =\frac{(x-2)^2}{4}
\]
当 \(x\) 为自然数时应向下取整。
因此,若 \(g_x\) 表示题目所求,则:
\[\begin{cases}
g_x = 0 , x=1,2,3 \\
g_x = g_{x-1} + f_x , x >3 \\
\end{cases}
\]
以此类推即可。
时间复杂度:\(O(n+T)\). (\(T\) 为数据组数)
实际得分:\(100pts\).
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
const int N=1e6+1;
inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
inline void write(ll x) {
if(x<0) {putchar('-');write(-x);return;}
if(x<10) {putchar(char(x%10+'0'));return;}
write(x/10);putchar(char(x%10+'0'));
}
ll f[N]; int n;
int main() {
f[1]=f[2]=f[3]=0ll; int T=read();
for(ll i=4;i<N;i++) f[i]=f[i-1]+(i-2)*(i-2)/4;
while(T--) write(f[read()]),putchar('\n');
return 0;
}
简易的代码胜过复杂的说教。