UESTC 1900 倒推数组 (找规律)
2013-12-19 19:53
302 查看
倒推数组
我们给出一个奇怪的公式:
其中min(x,y) 表示x,y中的较小值。如果你对求和符号不太熟悉,我们也可以写成程序语言的形式:
int f = 0;
for (int i = 1; i <= n; ++i)
for ( int j = 1; j <= n ; ++j)
f = f + min (a[i], a[j]);
注意到这里a是一个数组,下标从1到n,我们要求a数组满足以下条件:
1、a中所有元素都是正整数。
2、a中所有元素互不相同。
给定n和f(a)的值,请构造出合法的a数组,如果有多个a数组满足条件,输出字典序最小的答案。关于字典序的进一步说明请看Hint。
如果满足条件的数组不存在,输出-1。
第一行是一个数T(T <= 100),表示测试数据的组数。
每组测试数据包括一行,两个数n和F,代表数列元素个数以及f(a)的值。(1 <= n <=100, 1 <= F <= 10^9)
对于每一组测试数据,输出一行。
如果有解,输出n个数,数之间用空格隔开,否则输出-1。
行末不允许有多余的空格,最后一个元素(如果有解)后面没有空格。
2
2 10
2 2
1 7
-1
对于两个长度均为N,下标从1到N的数组A和B,我们称A的字典序严格小于B,当且仅当存在下标X <= N,使得对于所有1 <= i < x,均有A[i]和B[i]相等,同时满足A[x] < B[x]。
例如 长度为4的数组A= {1,2,3,4} 的字典序小于数组B={1,2,4,3},因为存在下标3,有 A[3] < B[3], 而且A[1]==B[1], A[2]==B[2]。
第五届ACM趣味程序设计竞赛第二场(正式赛)
解题思路:
对了!就是1,2,3,...,n-1, 同时,这n-1个数对答案的贡献已经尽可能小了,
Time Limit: 1000 ms Memory Limit: 65535
kB
Description
我们给出一个奇怪的公式:其中min(x,y) 表示x,y中的较小值。如果你对求和符号不太熟悉,我们也可以写成程序语言的形式:
int f = 0;
for (int i = 1; i <= n; ++i)
for ( int j = 1; j <= n ; ++j)
f = f + min (a[i], a[j]);
注意到这里a是一个数组,下标从1到n,我们要求a数组满足以下条件:
1、a中所有元素都是正整数。
2、a中所有元素互不相同。
给定n和f(a)的值,请构造出合法的a数组,如果有多个a数组满足条件,输出字典序最小的答案。关于字典序的进一步说明请看Hint。
如果满足条件的数组不存在,输出-1。
Input
第一行是一个数T(T <= 100),表示测试数据的组数。每组测试数据包括一行,两个数n和F,代表数列元素个数以及f(a)的值。(1 <= n <=100, 1 <= F <= 10^9)
Output
对于每一组测试数据,输出一行。如果有解,输出n个数,数之间用空格隔开,否则输出-1。
行末不允许有多余的空格,最后一个元素(如果有解)后面没有空格。
Sample Input
22 10
2 2
Sample Output
1 7-1
Hint
对于两个长度均为N,下标从1到N的数组A和B,我们称A的字典序严格小于B,当且仅当存在下标X <= N,使得对于所有1 <= i < x,均有A[i]和B[i]相等,同时满足A[x] < B[x]。例如 长度为4的数组A= {1,2,3,4} 的字典序小于数组B={1,2,4,3},因为存在下标3,有 A[3] < B[3], 而且A[1]==B[1], A[2]==B[2]。
Source
第五届ACM趣味程序设计竞赛第二场(正式赛)解题思路:
首先观察可以发现,数列中各元素的顺序不会影响f()函数的值,
为了字典序最小,最终的答案必然是从小到大排成一排的。
那么根据公式,最小的元素在答案中会被累加的次数是2n-1次,
次小的元素是2n-3次,这种累加的总值我们称之为对答案的“贡献”。
我们要构造最小字典序的解,那么前n-1个数最小分别是多少呢?
对了!就是1,2,3,...,n-1, 同时,这n-1个数对答案的贡献已经尽可能小了,
也就是说第n个数的值已经尽可能大了,如果这种情况下第n个数还是小于n,
那么显然答案是无解的,否则我们就已经成功构造出了最终的答案
#include<stdio.h> int main() { int i,j,T,t,n,f,sum; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&f); t=2*n-1; sum=0; for(i=1;i<n;i++) { sum+=i*t; t-=2; } if(f-sum<n) printf("-1\n"); else { for(i=1;i<n;i++) printf("%d ",i); printf("%d\n",f-sum); } } return 0; }
相关文章推荐
- 手把手教你使用FineUI开发一个b/s结构的取送货管理信息系统(附源码+视频教程(第5节))
- 通知的用法
- 代理的用法
- 如何在managedQuery()和getContentResolver().query()方法中实现结果去重
- Lucene实例(各种Query使用的例子)
- [UIImage resizableImageWithCapInsets:]使用注意
- make menuconfig requires the ncurse libraries——make menuconfig遇到的“困难”
- 聊聊并发(六)――ConcurrentLinkedQueue的实现原理分析
- UITouch类
- Build相关属性和调用系统信息的方法
- error loading /system/media/audio/ui/Effect_Tick.ogg
- mysql异常1366 - Incorrect decimal value: '' for column '' at row -1处理办法
- SystemUI的运行机制
- 理解 Android Build 系统
- 并发编程之Operation Queue和GCD
- 给iOS开发新手送点福利,简述UIPageControl的属性和用法
- Windows下安装设置Atlassian-Confluence-5.1.4并破解汉化(另附图解)
- APUE代码注记
- iOS开发中防止键盘挡住UITextField解决方案
- ORA-00001: unique constraint (...) violated并不一定是数据冲突