| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 48922 人关注过本帖, 10 人收藏
标题:[全民编程]76道高难度C++练习题.含NOI竞赛题.欢迎挑战
只看楼主 加入收藏
huozoo
Rank: 1
等 级:新手上路
帖 子:34
专家分:0
注 册:2007-6-28
收藏
得分:0 

有没什么好网站能下各种编译器的,要能下的哦```谢```

2007-06-29 12:47
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
收藏
得分:0 
蚂蚁那里有个devC++

Viva,espana!
2007-06-29 13:35
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
收藏
得分:0 
去搜索下主流编译器,网络里都有下载的!

Fight  to win  or  die...
2007-06-29 13:56
lous122
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2007-5-23
收藏
得分:0 
回复:(kai)关于第三题, 如果仔细观察一下这个图,那...
该程序有错误!

2007-06-29 16:51
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
收藏
得分:0 
楼主写错了,我在118的是第6题,130楼补充了蛇型

Viva,espana!
2007-06-29 20:06
野比
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:24
帖 子:1627
专家分:516
注 册:2007-5-24
收藏
得分:0 
不好意思... 太忙了, 没有仔细检查... 改正

女侠,约吗?
2007-06-29 20:37
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
收藏
得分:0 

这个题居然没有人做


//*************************************************************************
//7. 读入一行文本,包含若干个单词(以空格间隔,%结尾)。将其中以 A 开头的
//单词与以 N 结尾的单词,用头尾交换的办法予以置换。
//*************************************************************************
[code]
#include <iostream.h>

int main()
{
char str[]=\"I am a sb who are you%\";
char *p,*q,t;
p=str;

while(*p!='%')
{
if(*p==' ')
cout<<*p++; //输出空格
q=p;
while(*p!=' ' && *p!='%')
p++;
if(*p==' ')
if(*q=='a' || *(p-1)=='n')
{
t=*q;
*q=*(p-1);
*(p-1)=t;
}
while(q!=p)
cout<<*q++; //输出处理后的子串
}
return 0;
}

[此贴子已经被作者于2007-7-2 22:53:54编辑过]


Viva,espana!
2007-07-02 22:50
HJin
Rank: 6Rank: 6
等 级:贵宾
威 望:27
帖 子:401
专家分:0
注 册:2007-6-9
收藏
得分:0 

/*---------------------------------------------------------------------------
File name: C76-76.cpp
Author: HJin
Created on: 7/1/2007 02:30:50
Environment: Windows XP Professional SP2 English +
Visual Studio 2005 v8.0.50727.762

Modification history:

7/2/2007 15:39:35
-----------------------------------------------------------
1. totally ignore the hints in the original problem statement;
2. directly outputs the result for L = 3..6;
3. wrap the recursive call do_find() in find();
4. optimize the code so that it is more readable.


7/2/2007 07:15:41
-----------------------------------------------------------
add some analysis and correct a bug for S = 2.


经典 76 道编程题 之 76:

76. (省刻度尺问题)给定长度为 L 的直尺, L 为整数, 且 L≤ 40. 为了能一次直接
量出 1, 2, ..., L 的各种长度, 该尺内部至少要有多少条刻度 ? 请输出最少刻度
数(不含两端点)及每个刻度的位置. 测量长度时可利用两端点, 其位置分别为 0, L.

输入
由键盘输入 L.
输出
用文本文件按以下格式输出结果(文件名: ANS2.TXT):
第 1 行: S(最少刻度数)
第 2 行: 尺内 S 个刻度的位置
第 3 行至第 L+2 行: 每行输出 3 个用空格隔开的整数 t m n, 其中
1≤t≤L 为要测量的各长度, m, n 依次为该长度的起止刻度 (m<n).

例: 如果 L=6, 则一个正确的输出是:
2
1 4 提示:
1 0 1 (1) 最少刻度数 S 应满足:
2 4 6 C[S+2,2]=(S+2)*(S+1)/2≥L.
3 1 4 (2) 除两端点外, 第一个刻度可取为
4 0 4 A[1]=1, 第二个刻度可在 1, L-2,
5 1 6 L-1 这三个数中选取.
6 0 6

(Note that if we handle the case S<=2 (for L =2, 3, 4, 5, 6) directly,
we can totally ignore the hints.)


Analysis:
-----------------------------------------------------------

Let
a_0 < a_1 < ... < a_S < a_{S+1} (1)
be the markings on the ruler, where a_0 = 0, a_{S+1} = L.
We are searching a_1 to a_S.

A little bit high shcool math shows that
L/2 >= S >= (-3 + \sqrt{ 8L + 1 } )/2.
This tell us we should start our search at (-3 + \sqrt{ 8L + 1 } )/2.
It is easy to see that (1) gives a soln if and only if the set
{a_j - a_i: S+1>= j > i >=0}
equals the set {1, 2, ..., L}.


Sample output:
-----------------------------------------------------------

Please input the value for L (2 <= L <= 40)): 6
1 4
1 0 1
2 4 6
3 1 4
4 0 4
5 1 6
6 0 6
Press any key to continue . . .

Please input the value for L (2 <= L <= 40)): 40
9
1 2 3 4 10 17 24 29 35
1 0 1
2 0 2
3 0 3
4 0 4
5 24 29
6 4 10
7 3 10
8 2 10
9 1 10
10 0 10
11 24 35
12 17 29
13 4 17
14 3 17
15 2 17
16 1 17
17 0 17
18 17 35
19 10 29
20 4 24
21 3 24
22 2 24
23 1 24
24 0 24
25 4 29
26 3 29
27 2 29
28 1 29
29 0 29
30 10 40
31 4 35
32 3 35
33 2 35
34 1 35
35 0 35
36 4 40
37 3 40
38 2 40
39 1 40
40 0 40
Press any key to continue . . .

Reference:

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

*/


#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#define N 40

/**
global buffers and variables.
*/

int a[N+1]; // only a_0 to a_{S+1} are used.

// flags for 0..L --- if one number is used, it is set to 1
// only b_0 to b_L are used. Same thing for c[] and d[].
int b[N+1];

/** A soln will give us the following relation:
i = d[i] - c[i], i = 1..L.
*/
int c[N+1];
int d[N+1];

// mininum number of markings on the ruler
int S;

// total length of the ruler
int L;

/**
Recursive search function.
@param i --- the index in 2..S such that a_i is not assigned a vaule yet
@param p --- lower bound for a[i] (note it is not lower bound for i)
@param r --- upper bound for a[i]

Time complexity is O(L*S^2).
*/
void do_find(int i, int p, int r);

/**
A wrapper for do_find().

Time complexity is O(L^2*S^2).
*/
void find(int L);

/**
Check if we have a soln.

Time complexity is O(S^2).
*/
bool isSoln();

/**
Print the soln to an output stream.
*/
void print(std::ostream& os = cout);

void print(const string& s, std::ostream& os = cout);

int main(int argc, char** argv)
{
cout<<"Please input the value for L (2 <= L <= 40)): ";
cin>>L;

if(L<2 || L >40)
{
cout<<"incorrect input value.\n";
exit(1);
}

find(L);

return 0;
}

void do_find(int i, int p, int r)
{
// a[i] can be one of p..r
for (int j = p; j <= r; ++j) // O(L)
{
a[i] = j;

/** if all a_1 --- a_S are filled in
and they form a soln.

Clearly, this will be executed at most
once for the whole program.
*/
if ( i==S && isSoln() )
{

print();

std::ofstream ofs("ANS2.TXT");
if(!ofs)
{
cout<<"cannot open file ANS2.TXT.\n";
exit(1);
}

print(ofs);
ofs.close();

exit(1);
}

/**
This recursive call is very expensive. Most execution time
is wasted here.

Can you rewrite do_find() as an iterative procedure?
*/
if ( i<S && j< r )
{
//cout<<"i+1 = "<<i+1<<", j+1 = "<<j+1<<endl;
do_find(i+1, j+1, r); // recursive call
}
}
}

void print(std::ostream& os)
{
int i;

os<<S<<endl;

for(i=1; i<=S; ++i)
{
os<<a[i]<<" ";
}
os<<endl;

for(i=1; i<=L; ++i)
{
os<<i<<" "<<c[i]<<" "<<d[i]<<endl;
}
}

void print(const string& s, std::ostream& os)
{
os<<s;
}

void find(int L)
{
if(L<7)
{
string str;
ofstream ofs("ANS2.TXT");
if(!ofs)
{
cout<<"cannot open file ANS2.TXT.\n";
exit(1);
}

switch(L)
{
case 2:
str = "1\n";
str +="1 0 1\n";
str +="2 0 2\n";

break;

case 3:
str = "1\n";
str +="1 0 1\n";
str +="2 1 3\n";
str +="3 0 3\n";

break;

case 4:
str = "1 2\n";
str +="1 0 1\n";
str +="2 0 2\n";
str +="3 1 4\n";
str +="4 0 4\n";

break;

case 5:
str = "1 2\n";
str +="1 0 1\n";
str +="2 0 2\n";
str +="3 2 5\n";
str +="4 1 5\n";
str +="5 0 5\n";

break;

case 6:
str = "1 4\n";
str +="1 0 1\n";
str +="2 4 6\n";
str +="3 1 4\n";
str +="4 0 4\n";
str +="5 1 6\n";
str +="6 0 6\n";

break;
}

print(str);
print(str, ofs);
ofs.close();

return;
}

S = 0;
while( (S+2)*(S+1)/2 < L)
++S;

a[0] = 0;
while(1)
{
a[S+1] = L;

// program will be terminated in do_find()
// once a soln is found.
do_find(1, 1, L-1);

++S;
}
}

bool isSoln()
{
int k;
int m;
int idx;

// unset flags
for (k=1; k<= L; ++k)
b[k] = 0;

// double loop to check if 1..L are filled in
for (k=0; k<= S; ++k) // O(L*S)
{
for (m = k+1; m <= S+1; ++m) // O(L*S*S)
{
idx = a[m] - a[k];

// if not set
if ( b[idx] == 0 )
{
b[idx] = 1; // set it
c[idx] = a[k]; // record values
d[idx] = a[m];
}
}
}

k = 1;
while ( k<=L && b[k] != 0 )
++k;

/**
If all flags are set, we have a soln; otherwise we don't.
*/
return (k == L+1);
}

[此贴子已经被作者于2007-7-3 9:22:55编辑过]


I am working on a system which has no Chinese input. Please don\'t blame me for typing English.
2007-07-03 04:47
天空の城
Rank: 1
等 级:新手上路
帖 子:38
专家分:0
注 册:2007-7-1
收藏
得分:0 
第4题:对于行之间的重排列,我没有都显示出来,因为每一个N阶拉丁方阵在行重排列后都有N!个!
------------5阶拉丁方阵------------
12345
21453
34512
45231
53124
------------5阶拉丁方阵------------
12345
21453
34521
45132
53214
------------5阶拉丁方阵------------
12345
21453
35124
43512
54231
------------5阶拉丁方阵------------
12345
21453
35214
43521
54132
------------5阶拉丁方阵------------
12345
21534
34152
45213
53421
------------5阶拉丁方阵------------
12345
21534
34251
45123
53412

....还有很多。。。代码在楼下。

2007-07-03 09:11
天空の城
Rank: 1
等 级:新手上路
帖 子:38
专家分:0
注 册:2007-7-1
收藏
得分:0 

#include <vector>
#include <iostream>
#include <algorithm>
#include <cassert>
#include <cmath>
using namespace std;

int XAND(int a,int b)
{
int result=0;
for(int i=0;;i++)
{
if(a%10==b%10)
result+=((a%10)*pow(10,i));
a/=10;
b/=10;
if(a==0||b==0)
break;
}
return result;
}
bool VALID(int *p,int num)
{
for(int i=0;i<num-1;i++)
for(int j=i+1;j<num;j++)
if(XAND(p[i],p[j])!=0)
return false;
return true;
}
bool VALID(const vector<int>&vi)
{
int num=vi.size();
assert(num>=2);
for(int i=0;i<num-1;i++)
for(int j=i+1;j<num;j++)
if(XAND(vi[i],vi[j])!=0)
return false;
return true;
}
int IntFromArray(int p[],int num)
{
int result=0;
for(int i=num-1;i>=0;i--)
result+=p[i]*pow(10,i);
return result;
}
void Print(const vector<int>& rem,int n)
{
cout<<"------------"<<n<<"阶拉丁方阵------------\n";
for(int i=0;i<rem.size();i++)
{
cout<<rem.at(i)<<endl;
}
}
int factional(int n)
{
if(n==0||n==1)return 1;
return factional(n-1)*n;
}
void Func(vector<int>&rem,const vector<int>& vi,int n,int start=0)
{
static int num=factional(n-1);
static int NUM=n*num;
for(int i=start;i<start+num;i++)
{
rem.push_back(vi[i]);
if(start+num==NUM)
{
if(VALID(rem))
Print(rem,n);
}
else Func(rem,vi,n,start+num);
rem.pop_back();
}
}

void LaTinN(int n)
{
assert(n<9&&n>2);
int *p=new int[n];
for(int i=0;i<n;i++)
p[i]=i+1;
vector<int> vi,rem;
vi.push_back(IntFromArray(p,n));
while(next_permutation(p,p+n))
{
vi.push_back(IntFromArray(p,n));
}
delete[]p;
sort(vi.begin(),vi.end());
Func(rem,vi,n);
}
void main()
{
LaTinN(5);
}


2007-07-03 09:12
快速回复:[全民编程]76道高难度C++练习题.含NOI竞赛题.欢迎挑战
数据加载中...
 
   



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

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