赞
踩
题目描述
给定两个整数 n,m 问有多少三元组 (x,y,z) 满足:
输入格式
一行给出两个整数 n,m 。
输出格式
一个整数,代表答案。
输入输出样例
样例1:
输入:2 2 输出:6
样例2:
输入:3 15 输出:1
数据范围
对于20%的数据,满足1≤n≤100。
对于50%的数据,满足1≤n≤1000。
对于100%的数据,满足1≤n≤107,0≤m≤3n。
暴力枚举x,y,z,再判断合不合法,时间复杂度为O(n^3)。
暴力枚举x,y,根据条件2算出z,再判断合不合法,时间复杂度为O(n^2)。
暴力枚举x,再求出y,z的所有可能性。
那如何求y,z的所有可能性呢?不妨先令k=m−x,因为条件1,所以当k< 0时没有合法的解,只要讨论k≥0的情况。
首先先看一种简单的情况:n≥k
根据条件2,我们有y+z=k,因为n≥k,所以不存在不合法的结果。
因此,我们就是要求两个自然数之和为kk的数量,这个很明显是k+1k+1种,举个例子:
4=0+4=1+3=2+2=3+1=4+0
其实也就是k=i+(k−i)(0≤i≤k),共k+1种可能。
然后再看n<k的情况,我们依旧有y+z=k,但此时可能有不合法结果,甚至没有合法结果。
我们先设y=n,此时z=k−n=m−2n为最小值,如果z>n,那么代表没有合法结果,因为最小的可能也不符合要求,也就没有符合要求的结果了。
然后考虑有不合法结果也有合法结果,根据上面的例子4我们可以看出,分解的两端(即y,z分别取较大值时)最可能不符合要求,因此我们只要找出有多少不符合要求的值,再用总情况减去,就知道了有多少合法值。
很明显,从k=i+(k−i)(0≤i≤k)可以看出i>n不符合情况的数量是k-n,k-i不符合情况的数量也是k−n(正好与i不符合情况相反)。
总情况仍是k+1,因此,这时候符合情况的数量就是k+1−(k−n)∗2=2n−k+1。
我们把所有情况加起来就是答案了,时间复杂度为O(n)。
- #include<bits/stdc++.h>
- using namespace std;
- int k,s,ans;
- int main() {
- scanf("%d%d",&k,&s);
- for(int i=0; i<=k; i++) {
- int n=s-i,sum=0;
- if(n>=0) {
- if(n>k) {
- if(n-k>k)
- sum=0;
- else
- sum=2*k-n+1;
- } else
- sum=n+1;
- }
- ans+=sum;
- }
- printf("%d\n",ans);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。