N诺刷题(简单模拟)

目录

  • 01序列(P1001)
  • 日期
  • 单链表
  • 最长连续因子
  • 链表合并
  • 删除字符串
  • 阶乘求和
  • 括号的匹配

01序列(P1001)

对于长度为6位的一个01串,每一位都可能是0或1,一共有64种可能。它的前几个是:
000000
000001
000010
000011
000100
请按从小到大的顺序输出这64种01串。

#include
using namespace std;

int to_bin(int x){
	int bin[10] = {0}; 
	int num = 0;
	int ans = 0;
	while(x > 0){
		bin[num++] = x % 2;
		x /=2; 
	}
	//当前num为位数,逆序得到二进制数 
	for(int i = num-1;i>=0;i--){
		ans = ans*10+bin[i];
	}
	return ans; 
}
int main(){
	printf("%06d\n",0);
	for(int i =1;i<64;i++){
		printf("%06d\n",to_bin(i));
	}
}

日期

今天是2012年4月12日星期四,编写程序,输入今天开始到12月31日之间的任意日期,输出那一天是星期几。例如输入“5(回车)20(回车)”(5月20日),输出应为“Sunday”。

#include
using namespace std;

int main(){
	int m,d;//月份和日期
	scanf("%d",&m);
	scanf("%d",&d);
	int d_of_m[13] = {0,31,29,31,30,31,30,31,31,30,31,31,30};
	char week[7][20] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
	int nm = 4,nd=12,cnt=0;
	while(nm< m || nd < d){
		nd++;
		cnt++;
		if(nd == d_of_m[nm]+1){
			nm++;
			nd = 1;
		}
	}
	cnt += 4;
	int weekday = (cnt%7+7)%7;
	printf("%s\n",week[weekday]);
	return 0;
}

单链表

设节点定义如下

struct Node {
    int Element; // 节点中的元素为整数类型
    struct Node * Next; // 指向下一个节点
};

从键盘输入5个整数,将这些整数插入到一个链表中,并按从小到大次序排列,最后输出这些整数。

代码如下:

#include
using namespace std;

struct node{
	int element;
	node* next;
};
//创建链表 
node* create(int array[]){
	node *p, *pre,*head;
	head = new node();
	head->element = NULL;
	pre = head;
	for(int i =0;i<5;i++){
		p = new node();
		p->element = array[i];
		p->next = NULL;
		pre->next = p;
		pre = p;
	}
	return head;//返回头结点 
}
//排序
void sort(node* head){
	node *tail,*p,*t;//rail为末端元素,t为最小值的前一个元素 
	tail = head->next;
	while(tail->next != NULL){
		tail = tail->next;//移到末端 
	} 
	int min,i,j;
	for(int i =0;i<5;i++){//进行五次选择排序 
		p = head;
		t = p;
		min = p->next->element;
		for(int j =0;j<5-i;j++){//每次固定一位 
			if(min > p->next->element){
				min = p->next->element;
				t = p;//最小值前一位 
			}
			p = p->next;
		}
		if(tail == t->next){
			continue;//最小值已经在末尾 
		} 
		else{
			tail->next = t->next;
			t->next = t->next->next;
			tail = tail->next;//重新移到末尾
			tail->next = NULL; 
		}
	}
} 
int main(){
	int array[5];
	for(int i =0;i<5;i++){
		scanf("%d",&array[i]);
	}
	node* head = create(array);
	sort(head);//排序
	node *q = head->next;//第一个结点 
	while(q){
		if(q->next != NULL) printf("%d ",q->element);
		else printf("%d\n",q->element);
		q = q->next;
	} 
	return 0;
}

最长连续因子

输入一个整数,输出其最长连续因子。

例如

输入:60

输出:2 3 4 5 6

注意:1不算因子

思路:从2到n进行循环判断因子,注意记录最长连续因子的开始因子的方法。

#include
using namespace std;

int main(){
	int n;
	scanf("%d",&n);
	int firstans,j;//第一个因子
	int cnt = 0,temp;//最长因子个数,当前因子个数 
	for(int i =2;i<=n;i++){
		if(n%i == 0){//是因子 
			j =i;
			while(n%j == 0){
				temp++;
				j++;
			}
			if(cnt<temp){
				cnt = temp;
				firstans = i;
			}
		}
		temp = 0;
	}
	for(int i = firstans;i<firstans+cnt;i++) {
		if(i != firstans+cnt-1) printf("%d ",i);
		else printf("%d\n",i);
	}
	return 0;
}

链表合并

给定两个元素有序(从小到大)的链表,要求将两个链表合并成一个有序(从小到大)链表。

#include
using namespace std;
const int maxn = 110;
struct node{
	int data;
	node *next;
};
node* create(int array[],int s){
	node *head,*p,*pre;
	head = new node();
	head->data = NULL;
	pre = head;
	for(int i =0;i<s;i++){
		p = new node();
		p->data = array[i];
		p->next = NULL;
		pre->next = p;
		pre = p;
	}
	return head;
}
node* merge(node* L1, node* L2){
	node* headL = new node();//合并后的 
	headL->data = NULL;
	node* p = headL;
	node* p1 = L1->next;
	node* p2 = L2->next;
	while(p1 && p2){
		if(p1->data <= p2->data){
			headL->next = p1;
			headL = p1;
			p1 = p1->next;
		}else{
			headL->next = p2;
			headL = p2;
			p2 = p2->next;
		}
	}
	//剩余的
	if(p1){
		headL->next = p1;
	}else if(p2){
		headL->next = p2;
	}
	return p;
}
int main(){
	int s1,s2,array1[maxn],array2[maxn];
	scanf("%d",&s1);
	for(int i =0;i<s1;i++){
		scanf("%d",&array1[i]);
	}
	scanf("%d",&s2);
	for(int i =0;i<s2;i++){
		scanf("%d",&array2[i]);
	}
	node* L1 = create(array1,s1);
	node* L2 = create(array2,s2);
	node* L = merge(L1,L2);
	L = L->next;
	while(L){
		if(L->next != NULL) printf("%d ",L->data);
		else printf("%d\n",L->data);
		L = L->next;
	}
	return 0;
}

删除字符串

给你一个字符串S,要求你将字符串中出现的所有"gzu"(不区分大小写)子串删除,输出删除之后的S。
就是说出现“Gzu”、“GZU”、“GZu”、"gzU"都可以删除。

使用STL的string容器

#include
using namespace std;
const int maxn = 110;

int main(){
	string s,s1;
	cin >> s;
	s1 = s;//s1存放转小写后的s 
	transform(s1.begin(),s1.end(),s1.begin(),::tolower);//转小写
	int pos = 0;
	while((pos = s1.find("gzu")) != -1){
		s1.erase(pos,3);
		s.erase(pos,3);//原s同样删除 
	} 
	cout << s <<endl;
	return 0;
}

阶乘求和

求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字。

#include
using namespace std;

int main()
{
	int n;
	cin >> n;
	long long ans = 0, num = 1;
	for (int i = 1; i <= n; i++) {
		num *= i;
		ans += num;
	}
	cout << ans << endl;
	return 0;
}

括号的匹配

题意描述: 在算术表达式中,除了加、减、乘、除等运算外,往往还有括号。包括有大括号{},中括号[],小括号(),尖括号<>等。 对于每一对括号,必须先左边括号,然后右边括号;如果有多个括号,则每种类型的左括号和右括号的个数必须相等;对于多重括号的情形,按运算规则,从外到内的括号嵌套顺序为:大括号->中括号->小括号->尖括号。例如,{[()]},{()},{{}}为一个合法的表达式,而([{}]),{([])},[{<>}]都是非法的。

注意栈的应用,和goto函数跳出多重循环得到结果。

#include
using namespace std;
const int maxn = 265;

int main(){
	int n;
	scanf("%d",&n);
	while(n--){
		string str;
		cin>>str;
		map<char,int> mp;
		mp['<'] = 1;mp['('] = 2;mp['['] = 3;mp['{']=4;//括号优先级 
		stack<char> S;
		for(int i = 0;i<str.size();i++){
			if(str[i]=='<'|| str[i] == '(' || str[i] == '[' || str[i] == '{'){//左括号 
				if(!S.empty() && mp[str[i]]>mp[S.top()]){
					goto end;
				}
				S.push(str[i]);//将符合优先级的左括号压入栈 
			}else{//判断右括号 
				if(S.empty()){
					goto end;//没有读入左括号 
				}
				else if(!S.empty()){
					if(S.top()=='<'&&str[i]=='>' ||
						S.top()=='(' &&str[i] == ')'||
						S.top()=='[' &&str[i] ==']'||
						S.top()=='{' &&str[i]=='}'){
							S.pop();//如果匹配成功就弹出 
						}else{
							goto end;
						}
				}
			}
		}
		if(!S.empty()){//字符串遍历完之后还有未匹配的括号 
			goto end;
		}
		printf("YES\n");
		continue; //得到yes时直接跳出循环,不进行end	
	end:
		printf("NO\n");
	}
	return 0;
}

你可能感兴趣的:(刷题)