POJ2718

Smallest Difference
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 6509   Accepted: 1773

Description

Given a number of distinct decimal digits, you can form one integer by choosing a non-empty subset of these digits and writing them in some order. The remaining digits can be written down in some order to form a second integer. Unless the resulting integer
is 0, the integer may not start with the digit 0. 



For example, if you are given the digits 0, 1, 2, 4, 6 and 7, you can write the pair of integers 10 and 2467. Of course, there are many ways to form such pairs of integers: 210 and 764, 204 and 176, etc. The absolute value of the difference between the integers
in the last pair is 28, and it turns out that no other pair formed by the rules above can achieve a smaller difference.

Input

The first line of input contains the number of cases to follow. For each case, there is one line of input containing at least two but no more than 10 decimal digits. (The decimal digits are 0, 1, ..., 9.) No digit appears more than once in one line of the input.
The digits will appear in increasing order, separated by exactly one blank space.

Output

For each test case, write on a single line the smallest absolute difference of two integers that can be written from the given digits as described by the rules above.

Sample Input

1
0 1 2 4 6 7

Sample Output

28

Source

题意:

0-9中不重复的几个数,若分成两堆分别组合成一个十进制数(首位不能是0),问两个数的差最小是多少?

思路:

假设总共有n个数,很显然一堆所使用的数字个数应该为n/2,另一堆用剩下的。先选择n/2个数,利用全排列性质遍历所有排列顺序,也就遍历了第一个数,对第二个数也类似遍历,求其差的最小值即可。

C++中提供的

next_permutation

函数在帮助遍历全排列时可提供很大帮助。

代码:

Source Code

Problem: 2718		User: liangrx06
Memory: 204K Time: 469MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; const int INF = 1000000; int a[10];
int n; void input()
{
n = 0;
char ch;
while ( (ch = getchar()) != '\n' ) {
if (ch == ' ') continue;
a[n++] = ch - '0';
}
} void solve()
{
int res = INF;
int half = n/2;
int i, x, y;
do {
if (half >= 2 && a[0] == 0)
continue;
if (n - half >= 2 && a[half] == 0)
continue;
x = 0;
for (i = 0; i < half; i ++)
x = x * 10 + a[i];
y = 0;
for (i = half; i < n; i ++)
y = y * 10 + a[i];
int tmp = (x > y) ? (x - y) : (y - x);
if (tmp < res)
res = tmp;
} while (next_permutation(a, a + n));
printf("%d\n", res);
} int main(void)
{
int t; cin >> t;
getchar();
while (t--) {
input();
solve();
} return 0;
}

POJ3187

Backward Digit Sums
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5409   Accepted: 3121

Description

FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example,
one instance of the game (when N=4) might go like this:

    3   1   2   4

      4   3   6

        7   9

         16

Behind FJ's back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ's mental arithmetic capabilities. 



Write a program to help FJ play the game and keep up with the cows.

Input

Line 1: Two space-separated integers: N and the final sum.

Output

Line 1: An ordering of the integers 1..N that leads to the given sum. If there are multiple solutions, choose the one that is lexicographically least, i.e., that puts smaller numbers first.

Sample Input

4 16

Sample Output

3 1 2 4

Hint

Explanation of the sample: 



There are other possible sequences, such as 3 2 1 4, but 3 1 2 4 is the lexicographically smallest.

Source

题意:

给定1-n的某个排列,对其相邻的两个数相加得到n-1个数的数列,重复相加过程最终将得到一个数。

现在已知n以及操作后最终的结果sum,求原始排列(输出字典序最小的那个)。

思路:

简单分析后可以知道,原始排列中每个数的累加次数对应于n的二项式分解系数C(n,i)。对1-n的排列进行字典序遍历,第一个符合结果的排列就是答案。

代码:

Source Code

Problem: 3187		User: liangrx06
Memory: 204K Time: 16MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; const int INF = 1000000; int a[10];
int n;
int c[10]; int fact(int x)
{
int res = 1;
while (x)
res *= x--;
return res;
} void init()
{
int i;
for (i = 0; i < 10; i ++) {
a[i] = i+1;
if (i < n)
c[i] = fact(n-1)/fact(i)/fact(n-1-i);
}
} void solve(int sum)
{
int i;
do {
int tmp = 0;
for (i = 0; i < n; i ++)
tmp += a[i] * c[i];
if (tmp == sum)
break;
} while (next_permutation(a, a + n)); for (i = 0; i < n-1; i ++)
printf("%d ", a[i]);
printf("%d\n", a[i]);
} int main(void)
{
int sum; while (cin >> n >> sum) {
init();
solve(sum);
} return 0;
}

POJ3050

Hopscotch
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2775   Accepted: 1941

Description

The cows play the child's game of hopscotch in a non-traditional way. Instead of a linear set of numbered boxes into which to hop, the cows create a 5x5 rectilinear grid of digits parallel to the x and y axes. 



They then adroitly hop onto any digit in the grid and hop forward, backward, right, or left (never diagonally) to another digit in the grid. They hop again (same rules) to a digit (potentially a digit already visited). 



With a total of five intra-grid hops, their hops create a six-digit integer (which might have leading zeroes like 000201). 



Determine the count of the number of distinct integers that can be created in this manner.

Input

* Lines 1..5: The grid, five integers per line

Output

* Line 1: The number of distinct integers that can be constructed

Sample Input

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 2 1
1 1 1 1 1

Sample Output

15

Hint

OUTPUT DETAILS: 

111111, 111112, 111121, 111211, 111212, 112111, 112121, 121111, 121112, 121211, 121212, 211111, 211121, 212111, and 212121 can be constructed. No other values are possible.

Source

题意:

给定一片5*5的土地,一只牛在上面初始任意位置,它每次可以上下左右直线跳到任意位置。求牛跳5次所形成的的路径(比如111121)的个数。

思路:

递归穷竭搜索。

我的程序中考虑了路径重复问题,因此存储路径使用了set(其中无重复元素)。但特殊数据结构的维护似乎抵消了存储复杂度降低所带来的好处,因而时间复杂度仍不算低。

代码:

Source Code

Problem: 3050		User: liangrx06
Memory: 1064K Time: 219MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <set>
using namespace std; int a[5][5];
set<int> s[2][5][5]; void input()
{
int i, j;
for (i = 0; i < 5; i ++) {
for (j = 0; j < 5; j ++) {
cin >> a[i][j];
}
}
} void solve()
{
int i, j, k, x, y;
set<int>::iterator it; int pos[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
for (k = 0; k < 6; k ++) {
for (i = 0; i < 5; i ++) {
for (j = 0; j < 5; j ++) {
if (k == 0) {
s[k&1][i][j].insert(a[i][j]);
continue;
}
s[k&1][i][j].clear();
for (int m = 0; m < 4; m ++) {
x = i + pos[m][0];
y = j + pos[m][1];
if (x >= 0 && x < 5 && y >= 0 && y < 5) {
for (it = s[(k-1)&1][x][y].begin(); it != s[(k-1)&1][x][y].end(
); it ++)
s[k&1][i][j].insert((*it)*10 + a[i][j]);
}
}
}
}
} set<int> sall;
for (i = 0; i < 5; i ++) {
for (j = 0; j < 5; j ++) {
for (it = s[1][i][j].begin(); it != s[1][i][j].end(); it ++)
sall.insert((*it));
}
}
printf("%d\n", sall.size());
} int main(void)
{
input(); solve(); return 0;
}

AOJ0525

原题链接:

AOJ0525

题意:

题目大意是说,有一个煎饼器,可以烤R行C列的煎饼,煎饼可以正面朝上(用1表示),也可以背面朝上(用0表示),一次可以翻转一整行或一整列的煎饼。现在需要把尽量多的煎饼翻成正面朝上,给定煎饼的当前状态,问经过翻转后,最多能使多少煎饼正面朝上。

思路:

因为列数很大,行数只有10,所以枚举出10行所有的情况只有210=1024 种可能性。行翻转完毕后,统计每一行朝上的和朝下的个数,取最大值即可。

枚举的话,先从行开始,一共有2R种翻转可能,行翻转完毕再翻转列。列的翻转不必真的flip,只需要统计一下朝上的煎饼果子和朝下的煎饼果子,两者比较取其最大值即可。另外需要注意循环内外层不能弄反,我就是因为弄反了一直出错。

我看其他很多人用了bitset,关注了一下运行时间发现并无优势,自己用位操作照样实现的很好。

代码:

#include <iostream>
#include <cstdio>
using namespace std; const int C = 10000; int r, c;
int a[C]; void input()
{
cin >> r >> c;
fill(a, a+c, 0);
int x, n = 1;
for (int i = 0; i < r; i ++) {
for (int j = 0; j < c; j ++) {
scanf("%d", &x);
a[j] |= (x ? n : 0);
}
n <<= 1;
}
} void solve()
{
int res = 0;
for (int k = 0; k < (1<<r); k ++) {
int count = 0;
for (int j = 0; j < c; j ++) {
int count0 = 0, n = 1;
for (int i = 0; i < r; i ++) {
if ((a[j]^k)&n)
count0 ++;
n <<= 1;
}
count += ( (count0 > r/2) ? count0 : (r-count0) );
}
res = (res > count) ? res : count;
}
printf("%d\n", res);
} int main(void)
{
while (cin >> r >> c) {
if (!r && !c) break; fill(a, a+c, 0);
int x, n = 1;
for (int i = 0; i < r; i ++) {
for (int j = 0; j < c; j ++) {
scanf("%d", &x);
a[j] |= (x ? n : 0);
}
n <<= 1;
} solve();
}
return 0;
}

《挑战程序设计竞赛》2.1 穷竭搜索 POJ2718 POJ3187 POJ3050 AOJ0525的更多相关文章

  1. 《挑战程序设计竞赛》2.1 深度优先搜索 POJ2386 POJ1979 AOJ0118 AOJ0033 POJ3009

    POJ2386 Lake Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25366   Accepted: ...

  2. 挑战程序2.1.4 穷竭搜索>>深度优先搜索

      深度优先搜索DFS,从最开始状态出发,遍历一种状态到底,再回溯搜索第二种. 题目:POJ2386  思路:(⊙v⊙)嗯  和例题同理啊,从@开始,搜索到所有可以走到的地方,把那里改为一个值(@或者 ...

  3. 挑战程序2.1.5 穷竭搜索>>宽度优先搜索

    先对比一下DFS和BFS         深度优先搜索DFS                                   宽度优先搜索BFS 明显可以看出搜索顺序不同. DFS是搜索单条路径到 ...

  4. 《挑战程序设计竞赛》2.1 广度优先搜索 AOJ0558 POJ3669 AOJ0121

    AOJ0558 原文链接: AOJ0558 题意: 在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每 ...

  5. Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题

    King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazin ...

  6. 《挑战程序设计竞赛》2.3 动态规划-优化递推 POJ1742 3046 3181

    POJ1742 http://poj.org/problem?id=1742 题意 有n种面额的硬币,面额个数分别为Ai.Ci,求最多能搭配出几种不超过m的金额? 思路 据说这是传说中的男人8题呢,对 ...

  7. 挑战程序设计竞赛》P345 观看计划

                                                 <挑战程序设计竞赛>P345 观看计划 题意:一周一共有M个单位的时间.一共有N部动画在每周si时 ...

  8. POJ 2386 Lake Counting 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=2386 <挑战程序设计竞赛>习题 题目描述Description Due to recent rains, water has ...

  9. 《挑战程序设计竞赛》1.6 轻松热身 POJ1852

    Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12782   Accepted: 5596 Description ...

随机推荐

  1. WifiStateMachine学习笔记

    WifiStateMachine 1. 初始化 传入接口名称wlanInterface 新建一个WiFi类型的NetworkInfo 发一个ssid为null的广播 电池 NetworkManagem ...

  2. ibatis中<![CDATA[使用解释

    http://hi.baidu.com/taoxincheng0/blog/item/3916c4ec413f03c22e2e2160.html ibatis中什么时候需要用到: <![CDAT ...

  3. NIO之Channel聚集(gather)写入与分散(scatter)读取

    Channel聚集(gather)写入 聚集写入( Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel. 特别注意:按照缓冲区的顺序,写入 position ...

  4. 阻塞赋值与非阻塞赋值(verilog篇)

    阻塞赋值与非阻塞赋值(verilog篇) 2017-09-30 竹海 相约电子ee 相信刚刚接触verilog的读者,多少对阻塞赋值和非阻塞赋值仍有一些困惑.笔者在这篇文章,带领大家深入的理解这两者的 ...

  5. seo-mask -- 为单页应用创建一个适合蜘蛛爬取的seo网站

    seo-mask seo-mask是利用搜索引擎蜘蛛的爬取原理(蜘蛛只会爬取网页的内容,并不会关心解析网页里的css和js),制作一套专门针对seo的镜像网站,鄙人称它为针对seo的mask,让蜘蛛看 ...

  6. intent 启动activity、service的方法

    1.通过intent启动service. 通过传递一个Intent对象至Context.startService()将启动一个服务(或给予正在运行的服务以一个新的指令).Android调用服务的onS ...

  7. SpringBoot+MybatisPlus(多数据源和主从分离)

    简介 dynamic-datasource-spring-boot-starter 基于 springBoot2.0. 它适用于读写分离,一主多从的环境. 主数据库使用 INSERT UPDATE D ...

  8. iOS大文件分片上传和断点续传

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  9. mysql的两个备份语句

    适合多引擎混合(例如:myisam与innodb混合)的备份命令如下: mysqldump -A -R --triggers --master-data=2 --single-transaction  ...

  10. 带宽的单位为什么是Hz而不是bps?

    如果从电子电路角度出发,带宽(Bandwidth)本意指的是电子电路中存在一个固有通频带,这个概念或许比较抽象,我们有必要作进一步解释.大家都知道,各类复杂的电子电路无一例外都存在电感.电容或相当功能 ...