刘汝佳第二版算法竞赛入门经典-第三章数组和字符串习题答案(完整版)

习题共有12个,第一个题为得分(Score,ACM/ICPC Seoul 2005,UVa1585)

3-1

#include <stdio.h>
#include <string.h>
#define maxn 80+1
int main(int argc, char** argv)
{
	char buf[maxn];
	scanf("%s",buf);
	int sum=0,cnt=0;
	int len=strlen(buf);
	
	for(int i=0;i<len;i++)
	{
		if(buf[i]=='O')  sum+=(++cnt);
		else state=0;//连续处理方法,一次断开,直接为0 
	}
	printf("%d\n",sum);	
	return 0;
}

3-2

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#define maxn 256
using namespace std;
int main(int argc, char** argv)
{
	int sz;//字符数组中元素的个数 
	int cnt;//1,实时记录原子个数.2,在记录原子个数后,同时表征三个状态变量 0,1,-1 
    char buf[maxn];//输入由原子和数字组成的字符数组 
	char c;//记录数组中的每个元素,即每个原子和数字 ,均可以通过c转化 
	    char s;//s=c,记录原子所对应的英文大写字母,为取W[]的内容(也即原子对应的质量)做准备 
	    //int a; //a=c-'0,记录原子所对应的数字字符,为取原子对应的数量做准备
    double W[maxn];//记录每个原子所对应的质量  
    W['C']=12.01,W['H']=1.008,W['O']=16.0,W['N']=14.01;//初始化赋值 
    double ans=0;//记录实时的分子量 ,也即要求的答案
    cnt=-1;//初始化为-1,表示遇到了新原子 ,因为我们知道字符串第一个字符肯定是原子而不是数字 
 
	scanf("%s",buf);//输入字符串  
	sz=strlen(buf);
	
	for(int i=0;i<sz;i++){
	char c=buf[i];
	if(isupper(c)){//原子大写字母处理 
	    if(i) {
	    if(cnt==-1) cnt=1;//标记一:原子后面不带数目,则原子个数化为1 
	    ans+=W[s]*cnt;//计算的是上一次原子的质量 
	    }
	    s=c;//初始化本次原子 
	    cnt=-1;//一分为二,下一个字符要么是大写原子字母,要么是数字.为原子处理标记一和原子个数数字处理标记二做准备 
	}
	else{ //原子个数数字处理 
		if(cnt==-1) cnt=0;//标记二:(cnt=-1,说明是新数,那么无旧数,则令旧数为0) 
	    cnt=10*cnt+(c-'0');//旧数+新数 
	    }	//一下新旧数的概念是针对多位数建立的;如12,那么对2来说,1就是旧数.
	}
	
	
	if(cnt==-1) cnt=1;//加上最后一个 
	ans+=W[s]*cnt;
	
	printf("%.3lf\n",ans);//按要求输出结果 
	return 0;
}

3-3

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
const int maxn=10000 + 10;
using namespace std;

char s[maxn];
int main(int argc, char** argv)
{
	int a[10];
	memset(a,0,sizeof(a));
	cin>>s;
	for(int i=0;i<strlen(s);i++)	
	{
		if(s[i]=='0') a[0]++;
		if(s[i]=='1') a[1]++;
		if(s[i]=='2') a[2]++;
		if(s[i]=='3') a[3]++;
		if(s[i]=='4') a[4]++;
		if(s[i]=='5') a[5]++;
		if(s[i]=='6') a[6]++;
		if(s[i]=='7') a[7]++;
		if(s[i]=='8') a[8]++;
		if(s[i]=='9') a[9]++;
	}
	
	for(int i=0;i<10;i++)	
	{
		cout<<a[i]<<endl;
	}
	
	return 0;
}

3-4

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
const int maxn=100 + 10;
using namespace std;

int main(int argc, char** argv)
{
	int p,sz;
	char line[maxn];
	cin>>line;
	sz=strlen(line);
	for(p=1;p<sz;p++){
	if(sz%p) continue;
	bool ans=true;//循环的跳出实现可控 
	for(int i=0;i<p;i++){
		for(int j=i+p;j<sz;j+=p)
		{
			if(line[j]!=line[i]) {ans=false; break;}		
		}
		if(!ans) break;
	}
	if(ans) {cout<<p<<endl; break;}
	}
	return 0;
}

3-5

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>

struct Point{
	int x,y;
	Point(int x=0,int y=0):x(x),y(y) {}
};
typedef Point Vector; 
Point operator + (const Point& A,const Point& B)
{
	return Point(A.x+B.x,A.y+B.y);
}
using namespace std;

const int GSize=5;
vector<string> grid;
Vector ePos;
map<char,Vector> DIRS;

bool valid(const Point& p)
{
	return p.x>=0&&p.x<GSize&&p.y>0&&p.y<GSize;
}

void printGrid()
{
	for(int i=0;i<GSize;i++){
		for(int j=0;j<GSize;j++){
			//if(j) cout<<' ';//行首(0)不需要空格 
		    //cout<<grid[i][j];
			cout<<grid[i][j]<<" ";	
		}
	cout<<endl;
	}
}

bool tryMove(char cmd)
{
	//cout<<"move "<<cmd<<":"<<endl;
	if(!DIRS.count(cmd)) return false;
	assert(DIRS.count(cmd));
	Point p=ePos + DIRS[cmd];
	if(!valid(p)) return false;
	swap(grid[p.x][p.y],grid[ePos.x][ePos.y]);
	ePos=p;
	//printGrid();
	return true;
}

int main(int argc, char** argv)
{
    int t=1;
	string line;	
	DIRS['A']=Vector(-1,0);
	DIRS['B']=Vector(1,0);
	DIRS['L']=Vector(0,-1);	
	DIRS['R']=Vector(0,1);
	while(true){
		grid.clear();
		ePos.x=-1;ePos.y=-1;
		for(int i=0;i<GSize;i++){
			getline(cin,line);
			if(line=="Z") return 0;
			assert(line.size()==GSize);
			for(int j=0;j<GSize;j++)
			if(line[j]==' '){
				assert(ePos.x==-1&&ePos.y==-1);
				ePos.x=i;
				ePos.y=j;	
			}
		grid.push_back(line);	
		}
	
	//char move;
	string moves;
	while(true){
		getline(cin,line);
		assert(!line.empty());
		bool end=*(line.rbegin())=='0';
		if(!end) moves.append(line);
		else moves.append(line,0,line.size()-1);
		if(end) break;
	}
	bool legal=true;
	for(int i=0;i<moves.size();i++)
		if(!tryMove(moves[i])) {legal=false;break;}
	if(t>1) cout<<endl;
	cout<<"Puzzle #"<<t++<<":"<<endl;
	if(legal) printGrid(); 
    else cout<<"This puzzle has no final configuration."<<endl;
    }
	return 0;
}

3-6

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;

struct Point{
	int  x,y;
	Point(int x=0,int y=0):x(x),y(y) {} 
};
typedef Point Vector;

Vector operator+ (const Vector& A,const Vector& B)
{
	return Vector(A.x+B.x,A.y+B.y);
}

int R,C;
inline bool valid(const Point& p)
{
	return p.x>=0&&p.x<R&&p.y>=0&&p.y<C;
}

const int MAXC=16;
char grid[MAXC][MAXC];

int main(){
	
	int  t=0,bufLen;
	char buf[MAXC];	
	const Vector dLeft(0,-1),dUp(-1,0),dRight(0,1),dDown(1,0);
	
	while(cin>>R>>C){
		t++;
		vector<Point> eligible;
		vector<int>   down,across;
		
		if(t>1) puts("");
		cout<<"puzzle #"<<t<<":"<<endl;
	
    	for(int i=0;i<R;i++){
    	cin>>grid[i];
    		for(int j=0;j<C;j++){
    			if(grid[i][j]=='*') continue;
    			Point p(i,j),left=p+dLeft,up=p+dUp;
    			bool  isCross=!valid(left)||grid[left.x][left.y]=='*';
    			bool  isDown =!valid(up)||grid[up.x][up.y]=='*';
    			if(isCross) across.push_back(eligible.size());
    			if(isDown)  down.push_back(eligible.size());
    			if(isCross||isDown)  eligible.push_back(p);
    		}
		} 
	
	puts("Across");
	for(auto n:across){
		bufLen=0;
		memset(buf,0,sizeof(buf));
		Point p=eligible[n];
		while(valid(p)&&grid[p.x][p.y]!='*'){
			buf[bufLen++]=grid[p.x][p.y];
			p=p+dRight;
		}
		printf("%3d.%s\n",n+1,buf);	
	}
    
    puts("Down");
	for(auto n:down){
		bufLen=0;
		memset(buf,0,sizeof(buf));
		Point p=eligible[n];
		while(valid(p)&&grid[p.x][p.y]!='*'){
			buf[bufLen++]=grid[p.x][p.y];
			p=p+dDown;
		}
		printf("%3d.%s\n",n+1,buf);	
	}
}
	return 0;
}

3-7

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;

struct ChCnt{
	int  cnt;
	char c;
	void init(char ch='A')
	{
		c=ch;
		cnt=0;
	} 
	ChCnt()  {init();}
	bool operator < (const ChCnt& cc2)
    {
	    return cnt>cc2.cnt||(cnt==cc2.cnt&&c<cc2.c);//次数+字典序 
    }
};

int main(int argc, char** argv)
{
	int m,n;
	vector<string> seqs;
	char IDX[256]={0};
	IDX['A']=0;
	IDX['C']=1;
	IDX['G']=2;
	IDX['T']=3;
	string line;
	string ansStr;//变量准备完毕 
	
	seqs.clear();
	cin>>m>>n;//m个长度为n的字符串 
	for(int k=0;k<m;k++){//输入 
	cin>>line;
	assert(line.size()==n);
	seqs.push_back(line);
    }
    
	//核心操作 
	int ans=0;
	vector<ChCnt> ccs(4);//必须是括号而非中括号 
	
	for(int j=0;j<n;j++){//n=8  j
	ccs[0].init('A');
	ccs[1].init('C');
	ccs[2].init('G');
	ccs[3].init('T');
		for(int i=0;i<m;i++) //m=5 i
		ccs[IDX[seqs[i][j]]].cnt++;
	sort(ccs.begin(), ccs.end());
	ansStr += ccs.front().c;
	ans += (m - ccs.front().cnt);
    }
	cout<<ansStr<<endl<<ans<<endl;//输出 
	
	return 0;
}

3-8

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
const int maxn=3000 + 10;
map<int,int> Pos;

void solve(int n,const int d,string& ans,int& r)
{
    assert(n%d&&n<d);//不能整除且余数小于被除数 
    
    ans=".";
	Pos.clear();
	
	while(true){
		n*=10;
		int p=Pos[n];
		if(p==0) Pos[n]=ans.size();
		else{
			r=ans.size()-p;
			if(r>50) {ans.erase(p+50);ans+="...";}
			ans.insert(p,"(");
			ans+=")";
			break;
		}
		if(n<d) {ans+='0';continue;}//补0
		int div=n/d,mod=n%d;
		ans+=(char)(div+'0');
		n=mod;
		if(n==0) {ans+="(0)";r=-1;break;	} 
	} 
}

int main(int argc, char** argv)
{
	int a,b;
	while(cin>>a>>b){
	string ans="0.(0)";//赋值对答案无影响,标记出答案的样式,后面会进行修改 
	int r=1;
	if(a%b)
	solve(a%b,b,ans,r);//四个参数:余数,被除数,循环小数,循环节长度 例5/43=0.(116279069767441860465) 21 
	
    cout<<a<<"/"<<b<<"="<<a/b<<ans<<endl;
    cout<<"repeating cycle number:"<<r<<endl;
	cout<<endl;	
	}
   
	return 0;
}

3-9

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
//const int maxn=100000 + 10;
//char t[maxn],s[maxn];
int main(int argc, char** argv)
{
	string s,t;
	while(cin>>s>>t){
		bool ok=true;
		for(int i=0,j=0;i<s.size();i++,j++){
			while(j<t.size()&&t[j]!=s[i]) j++;
			if(j==t.size()) {ok=false;break;}
		}
		printf("%s\n",ok?"YES":"NO");
//		if(ok=0)
//		cout<<"NO"<<endl;
//		else
//		cout<<"YES"<<endl;
	}
	
	return 0;
}

3-10

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;

struct rectangle{
	int  w;//长 
	int  h;//宽 
}a[6];
bool cmp(rectangle x,rectangle y)
{
    return x.w<y.w;
}

fun(int a,int b,int c,int d,int e,int f)
{
	int brr[6];
	brr[0]=a;
	brr[1]=b;
	brr[2]=c;
	brr[3]=d;
	brr[4]=e;
	brr[5]=f;
	sort(brr,brr+6);
	if(brr[0]==brr[1]&&brr[2]==brr[3]&&brr[4]==brr[5])
	return true;
	else
	return false;
}
int main(){
	
	for(int i=0;i<6;i++) 	
		cin>>a[i].w>>a[i].h;
    
    sort(a,a+6,cmp);
    
    //保证输入的长宽高六个数,只有三个不同	
    bool ok;
    //cout<<a[0].w<<a[0].h<<a[2].w<<a[2].h<<a[4].w<<a[4].h<<endl;
    ok=fun(a[0].w,a[0].h,a[2].w,a[2].h,a[4].w,a[4].h);
    
    int j=0;//保证有三对相同的数 
    for(;j<5;j+=2){
    	if(a[j].h!=a[j+1].h||a[j].w!=a[j+1].w)
		break;	
	}
	
	if(j==6&&ok)  cout<<"YES"<<endl;
	else      cout<<"NO"<<endl; 
	return 0;
}

3-12:

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值