数列 {An} 为N的一种排列。
例如N=3,可能的排列共6种:
1, 2, 3 1, 3, 2 2, 1, 3 2, 3, 1 3, 1, 2 3, 2, 1
定义函数F:
其中|X|表示X的绝对值。
现在多多鸡想知道,在所有可能的数列 {An} 中,F(N)的最小值和最大值分别是多少。
1, 2, 3 1, 3, 2 2, 1, 3 2, 3, 1 3, 1, 2 3, 2, 1
第一行输入1个整数T,表示测试用例的组数。
( 1 <= T <= 10 )
第二行开始,共T行,每行包含1个整数N,表示数列 {An} 的元素个数。
( 1 <= N <= 100,000 )
共T行,每行2个整数,分别表示F(N)最小值和最大值
2 2 3
1 1 0 2
对于N=3:
- 当{An}为3,2,1时可以得到F(N)的最小值0
- 当{An}为2,1,3时可以得到F(N)的最大值2
对于60%的数据有: 1 <= N <= 100
对于100%的数据有:1 <= N <= 100,000
题目一开始没读懂,意思是:在{An}的所有排列中,能让F(N)取得的最大最小值为多少。
每四个数 例如 5,6,7,8,我们把它们两两一组 |||8-6|-7|-5|=0,最小值是0;猜测最小值的变化也是4个一组
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int nums = sc.nextInt(); for (int i = 0; i<nums; i++){ int N = sc.nextInt(); maxandmin(N); } } public static void maxandmin(int N){ if (N==1||N==2){ System.out.println("1 1"); return; } //之后每4个一组 0011 int min = getmin(N); int max = N-getmin(N-1); System.out.println(min + " " + max); } public static int getmin(int N){ int temp = (N-2)%4; if (temp==1 || temp==2){ return 0; } else return 1; } }
#include <iostream> #include <algorithm> using namespace std; int F[100001][2]; void getMinMax(int N){ for(int i=1;i<=N;i++){ if(i==1){ F[1][0] = 1; F[1][1] = 1; } F[i][0] = (i%4 == 1 || i%4 == 2)? 1:0; F[i][1] = abs(F[i-1][0]-i); } } int main(){ int t; cin>>t; while(t--){ int n; cin>>n; getMinMax(n); cout<<F[n][0]<<" "<<F[n][1]<<endl; } return 0; }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int n = scan.nextInt(); for(int i=0;i<n;i++) { int N = scan.nextInt(); System.out.println(min(N)+ " "+max(N)); } } public static int min(int n) { if(n % 4 == 0 || (n+1) % 4 == 0) { return 0; }else { return 1; } } public static int max(int n) { if(n == 1) { return 1; } if(n == 2) { return 1; } return Math.abs(min(n-1)-n); } }
这道题没啥意义,直接作弊吧。
#include using std::cin; using std::cout; using std::endl; class An { private: int m_max; int m_min; int m_N; public: An(int n): m_N{n}, m_min{min(n)}, m_max{max(n)} {} int get_min() { return this->m_min; } int get_max() { return this->m_max; } private: int min(int x) { if (x % 4 == 1 || x % 4 == 2) { return 1; } if (x % 4 == 3 || x % 4 == 0) { return 0; } } int max(int x) { return x - min(x - 1); } }; int main(int argc, char** argv) { int T; // 输入T位数字 int N; // N 数列An的个数 cin >> T; while(T-- != 0 && cin >> N) { An tmp{N}; // 输出结果 cout << tmp.get_min() << " " << tmp.get_max() << endl; } return 0; }
n = int(input().strip()) for i in range(n): num = int(input().strip()) if num == 1&nbs***bsp;num==2: print(1, 1) continue if num%2: if ((num-1)//2)%2: pre_low = 1 else: pre_low = 0 high = num - pre_low if pre_low: low = 0 else: low = 1 print(low, high) else: if (num//2)%2: pre_low = 1 else: pre_low = 0 high = num - pre_low print(pre_low, high)
题目一开始没读懂,意思是:在{An}的所有排列中,能让F(N)取得的最大最小值为多少。
每四个数 例如 5,6,7,8,我们把它们两两一组 |||8-6|-7|-5|=0,最小值是0;猜测最小值的变化也是4个一组。看到min只有2种取值。0,1,最大值自然就是N-getmin(N-1)
对最小值的求解,当数组是上升或者下降的时候均满足,其值只能是1或者0,通过函数calc_min()
直接计算。
最大值的求解,不能通过回溯去生成序列(时间复杂度太高),由函数F
的公式:,要使得
F(x)
最大,即令F(x-1)
最小,即N - calc_min(N-1)
。
def calc_min(N): min_li = [i for i in range(N,0,-1)] res = min_li[0] for i in range(1,N): res = abs(res-min_li[i]) return res def calc_min_max(N): min_val = calc_min(N) max_val = N - calc_min(N-1) print("{} {}".format(min_val,max_val)) def main(): T = int(input()) for i in range(T): N = int(input()) if N == 1: print("1 1") else: calc_min_max(N) main()