标题:[全民编程]76道高难度C++练习题.含NOI竞赛题.欢迎挑战
只看楼主
HJin
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:401
专家分:0
注 册:2007-6-9
得分:0 
...
delete a;
for(int i=0;i<n;i++)
{
delete b[i];
delete c[i];
}
delete b;
delete c;
...
void f()
{
...
for(int k=0;k<n;k++)
for(int i=0;i<n-k;i++)
for(int r=0;r<k;r++)
{
...
}
}


very nicely done, bro.

1. You code has bugs for allocating/deallocating --- use delete []
instead of delete for arrays;
2. Your algorithm is a dynamic programming scheme and has O(n^3)
time complexity.

I am thinking about this can be done use a greedy algorithm with O(n^2)
time complexity.

3. It would be better if your soln provided the optimal soln --- this
means you need to track back where the parentheses are put.

[此贴子已经被作者于2007-7-15 14:45:27编辑过]


I am working on a system which has no Chinese input. Please don\'t blame me for typing English.
2007-07-15 14:09
pboyin
Rank: 1
等 级:新手上路
帖 子:8
专家分:5
注 册:2007-5-28
得分:0 
好难哦,高手们做出来,可 不可以贴出来啊

[url=http://www.beishan.info]美国主机[/url]
2007-07-15 19:30
zl_breeze
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-4-23
得分:0 
回复:(野比)[全民编程]76道高难度C++练习题.含NOI竞...

// 第一题, 用递归做

#include<iostream>
using namespace std;

int number[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, result[ 10 ], n1, n2, n3;
bool used[ 10 ] = { 0 };
void Find( int i );
void print();

int main()
{
Find( 0 );
return 0;
}

void Find( int i )
{
if( i == 10 )
{
n1 = result[ 0 ] * 10000 + result[ 1 ] * 1000 + result[ 2 ] * 100 + result[ 3 ] * 10 + result[ 4 ];
n2 = result[ 3 ] * 100 + result[ 5 ] * 10 + result[ 6 ];
n3 = result[ 7 ] * 10000 + result[ 8 ] * 1000 + result[ 9 ] * 100 + result[ 3 ] * 10 + result[ 4 ];
if( n1 + 2 * n2 == n3 )
print();
}
else{
for(int k = 0; k < 10; k++ )
{
if(!used[k])
{
used[k]=true;
result[i]=number[k];
Find(i+1);
used[k]=false;
}
}
}
}

void print()
{
cout << "\t" << result[ 0 ] << result[ 1 ] << result[ 2 ] << result[ 3 ] << result[ 4 ] << endl;
cout << "\t" << " " << " " << result[ 3 ] << result[ 5 ] << result[ 6 ] << endl;
cout << "+\t" << " " << " " << result[ 3 ] << result[ 5 ] << result[ 6 ] << endl;
cout << "----------------------" << endl;
cout << "\t" << result[ 7 ] << result[ 8 ] << result[ 9 ] << result[ 3 ] << result[ 4 ] << endl;
}

结果:
29786
850
+ 850
------------
31486

[此贴子已经被作者于2007-7-15 22:52:30编辑过]


2007-07-15 22:41
zl_breeze
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-4-23
得分:0 
回复:(野比)[全民编程]76道高难度C++练习题.含NOI竞...

//第二题,借用二进制来解题
#include< iostream>

using namespace std;

void main()
{
int A, B, C, D, E;
for( int i = 0; i < 32; i++ )
{
A = ( i & 16 ) >> 4;
B = ( i & 8 ) >> 3;
C = ( i & 4 ) >> 2;
D = ( i & 2 ) >> 1;
E = i & 1;
if( A == 1 && B != 1 )
continue;
if( ( B == 1 && C == 1 ) || ( B == 0 && C == 0 ) )
continue;
if( ( C == 1 && D == 0 ) || ( C == 0 && D == 1 ) )
continue;
if( D == 0 && E == 0 )
continue;
if( E == 1 && !( A == 1 && D == 1 ) )
continue;
if( A == 1 )
cout << "A ";
if( B == 1 )
cout << "B ";
if( C == 1 )
cout << "C ";
if( D == 1 )
cout << "D ";
if( E == 1 )
cout << "E";
}
}


程序输出参加了的人,为:C和D。

2007-07-15 23:11
HJin
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:401
专家分:0
注 册:2007-6-9
得分:0 
回复:(野比)[全民编程]76道高难度C++练习题.含NOI竞...

/*---------------------------------------------------------------------------
File name: C76-45.cpp
Author: HJin (email: fish_sea_bird [at] yahoo [dot] com)
Created on: 7/3/2007 17:18:43
Environment: Windows XP Professional SP2 English +
Visual Studio 2005 v8.0.50727.762

Modification history:
===========================================================================


Problem statement:
---------------------------------------------------------------------------
经典 76 道编程题 之 45:

45. (数列的最小代价) 给定一个正整数序列,例如:4,1,2,3, 不改变数的位置把
它们相加, 并且由括号来标记每一次加法所得到的和。例如:((4+1)+(2+3))=
((5)+(5))=10. 除去原数4、1、2、3之外,其余都为中间结果,如:5,5,10, 将中
间结果相加,得到:5+5+10=20, 数 20 称为此数列的一个代价。对于另一种算法:
(4+((1+2)+3))=(4+((3+3))=(4+(6))=10, 得到数列的另一个代价为:3+6+10=19.
若给出 N 个数的数列,求出此数列的最小代价。


Analysis:
---------------------------------------------------------------------------
The minimum sequence price (SMP) problem:

For n numbers a_1 ... a_n, we need to do n-1 additions, thus there are
n-1 intermediate results. Our goal is to make the sum of these n-1
intermediate results as small as possible.

Let P_{i..j} be the sub-problem for a_i ... a_j, 1<=i <=j <=n, and m[i, j]
the corresponding minimum price. Then

m[i, j] = 0, if i=j; (1)
= min_{i<=k<j} { m[i, k], m[k+1, j]} + (a_i + ... + a_j)
if i<j.

Note that the formula (1) is very similar to the matrix chain order problem
introduced on CLRS [2]'s book.

m[1, n] gives the minimum price for a_1 .... a_n. To track back where we should
put the parentheses, we use another matrix to keep record of the k which minimizes
the equation in (1).


Sample output:
---------------------------------------------------------------------------
Optimal solution is:
(4+((1+2)+3))
Minimum sequence price is 19.
Press any key to continue . . .

Optimal solution is:
(((((1+2)+3)+(4+5))+(6+7))+((8+9)+10))
Minimum sequence price is 173.
Press any key to continue . . .

Optimal solution is:
(((1+-2)+(9+-3))+10)
Minimum sequence price is 25.
Press any key to continue . . .

Reference:
---------------------------------------------------------------------------

1. 野比, [全民编程]76道高难度C++练习题
http://bbs.bc-cn.net/viewthread.php?tid=147967

2. CLRS, introduction to algorithms, 2nd ed, MIT press.

*/

#include <iostream>
using namespace std;

#define INFPos (~(1<<31))
#define DIM(a) sizeof( (a) ) / sizeof ( (a)[0] )

/** Implement formula (1).

O(n^3) time + O(n^2) space.
*/
int smp(int*a, int n);

/**
Print the optimal solutions (the parentheses) recursively.
*/
void printOptSoln(int**s, int*a, int i, int j);


template <class T>
T** new2dInit(int row, int col)
{
T** arr2d = new T*[row];
int i;
int j;

for(i=0; i<row; ++i)
{
arr2d[i] = new T[col];
}

for(i=0; i<row; ++i)
{
for(j=0; j<col; ++j)
{
arr2d[i][j] = T();
}
}

return arr2d;
}

template <class T>
void delete2d(T** arr2d, int row)
{
for(int i=0; i<row; ++i)
{
delete [] arr2d[i];
}

delete [] arr2d;
}


int main()
{
// test #1
int a[] = {4, 1, 2, 3};
smp(a, DIM(a));

// test #2
//int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//smp(a, DIM(a));


// test #3 --- numbers can be negative
//int a[] = {1, -2, 9, -3, 10};
//smp(a, DIM(a));

return 0;
}

int smp(int*a, int n)
{
int** m;
int** s;

int i;
int j;
int k;
int l; // length of a subproblem P_{i..j}
int q;
int sum; // a_i + ... + a_j

m = new2dInit<int>(n, n);
s = new2dInit<int>(n, n);

for (l=2; l<=n; ++l)
{
for (i=0; i<=n-l; ++i)
{
j = i+l-1;

// assign m[i,j] to be \+inf
m[i][j] = INFPos;

/**
This sum has been repeatedly calculated.

You could use another 2d buffer to store the
results. The situation is that we have two choices here:

choice #1: 3n^2 space + n^3 time (allocate a new 2d buffer for the sums)
choice #2: 2n^2 space + 2n^3 time.

As implemented, we are using choice #2.
*/
sum = 0;
for (k=i; k<=j; ++k)
{
sum += a[k];
}

for (k=i; k<j; ++k)
{
// implement (1)
q = m[i][k] + m[k+1][j] + sum;
if ( m[i][j] > q )
{
m[i][j] = q;
s[i][j] = k;
}
}
}
}

cout<<"Optimal solution is:\n";
printOptSoln(s, a, 0, n-1);

j = m[0][n-1]; // reuse j to keep m[0][n-1]

cout<<"\nMinimum sequence price is "<<j<<"."<<endl;

// free memory
delete2d<int>(m, n);
delete2d<int>(s, n);

return j;
}

void printOptSoln(int** s, int*a, int i, int j)
{
if(i==j)
{
cout<<a[i];
}
else
{
cout<<"(";
printOptSoln(s, a, i, s[i][j]); // i..k
cout<<"+";
printOptSoln(s, a, s[i][j]+1, j); // k+1..j
cout<<")";
}
}


I am working on a system which has no Chinese input. Please don\'t blame me for typing English.
2007-07-16 23:43
zl_breeze
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-4-23
得分:0 
回复:(野比)[全民编程]76道高难度C++练习题.含NOI竞...

//第三题
#include<iostream>

using namespace std;

int main()
{
int n;
cout << "Input the number N, and you must make sure that N is between 3 and 20:\n";
cin >> n;
if( n < 4 || n > 19 )
cout << "Input Error!!\n";
else {
for ( int i = 0; i < n; i ++ )
{
for ( int j = 0; j < n; j ++ )
{
if( j == 0 || i == 0 || n - j == 1 || n - i == 1 )
cout << "T";
else if( j == 1 || i == 1 || n - j == 2 || n - i == 2 )
cout << "J";
else if( i < n / 2 && i - j > 0 )
cout << j - 1;
else if( i < n / 2 && i - j < 0 && j - i > n - 2 - 2 * i )
cout << n - j - 2;
else if( i < n / 2 )
cout << i - 1;
else if( i >= n / 2 && i > j && j < n - 1 - i )
cout << j - 1;
else if( i >= n / 2 && i < j )
cout << n - 2 - j;
else cout << n - 2 - i;
}
cout << endl;
}
}
return 0;
}


2007-07-17 10:29
zl_breeze
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-4-23
得分:0 
回复:(zl_breeze)回复:(野比)[全民编程]76道高难...

//第五题
#include <iostream>
#include <string>
using namespace std;

int main()
{
int num, n, temp;
string res, mid;
mid = " ";
cout << "输入要转换的数:\n";
cin >> num;
cout << "你要把它转换成几进制?\n";
cin >> n;
while( num )
{
temp = num % n;
num /= n;
if( temp < 10 )
mid[ 0 ] = '0' + temp;
else mid[ 0 ] = 'A' + temp - 10;
res = mid + res;
}
cout << res << endl;
return 0;
}

[此贴子已经被作者于2007-7-17 10:47:58编辑过]


2007-07-17 10:47
zl_breeze
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-4-23
得分:0 

//第四题
#include <iostream>
using namespace std;

int main()
{
int *arr, n;
cout << "你要想打印几阶方正?\n";
cin >> n;
arr = new int[ n ];
for( int i = 0; i < n; i++ )
arr[ i ] = i + 1;
for( int j = 0; j < n; j++ )
{
int k = j;
while( true )
{
cout << arr[ k ] << " ";
k ++;
if( k == n )
k = 0;
if( k == j )
break;
}
cout << endl;
}
return 0;
}

[此贴子已经被作者于2007-7-17 10:59:22编辑过]


2007-07-17 10:59
xinghuo
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2007-7-17
得分:0 

76道完整版有答案没?


2007-07-17 12:49
げ訾澐み
Rank: 1
等 级:新手上路
帖 子:37
专家分:0
注 册:2007-7-18
得分:0 
看看

2007-07-18 09:32



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-147967-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 1.459553 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved