http://47.99.57.28/problem/
//W8
//1847 B 表达式求值(栈和队列) //PRN
//1850 E 不同出栈情况(栈和队列)
//1852 -A 队列组合(栈和队列)
//2355 -F 稀疏矩阵相乘
/*
//W9 课后
//1870 C 根据上排给出十个数,在其下排填出对应的十个数(栈和队列)
//W9上机
//1863 G 求整数的各个组合之和(栈和队列)
*/
(主函数搭配懒狗模板见文末)
1870 根据上排给出十个数,在其下排填出对应的十个数(栈和队列)
1 2 3 0 4 5 6 10 8 7
0 1 2 3 4 5 6 7 8 9
1 2 3 0 4 5 6 10 8 7
2 1 0 6 0 0 1 0 0 0
0 1 2 3 4 5 6 7 8 9
6 2 1 0 0 0 1 0 0 0
1861 约瑟夫环
如何使用指针需要关注
//1861 约瑟夫环
#include <stdio.h>
#include <stdlib.h>
typedef struct node{ int number; struct node * next;} person;
person * initLink(int n){
person * head=(person*)malloc(sizeof(person));
head->number=1;
head->next=NULL;
person * cyclic=head; int i;
for (i=2; i<=n; i++) {
person * body=(person*)malloc(sizeof(person));
body->number=i;
body->next=NULL;
cyclic->next=body;
cyclic=cyclic->next;}
cyclic->next=head;//首尾相连
return head;}
void findAndKillK(person * head,int k,int m){
person * tail=head;
//找到链表第一个结点的上一个结点,为删除操作做准备
while (tail->next!=head) {tail=tail->next;}
person * p=head;
//找到编号为k的人
while (p->number!=k) { tail=p; p=p->next;}
//从编号为k的人开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了,
while (p->next!=p) {int i;
//找到从p报数1开始,报m的人,并且还要知道数m-1de人的位置tail,方便做删除操作。
for (i=1; i<m; i++) {tail=p; p=p->next;}
tail->next=p->next; free(p);//从链表上将p结点摘下来
//printf("出列人的编号为:%d\n",p->number);
p=tail->next;} //继续使用p指针指向出列编号的下一个编号,游戏继续
//printf("出列人的编号为:%d\n",p->number);
printf("%d",p->number); free(p);}
int main() { int n; scanf("%d",&n); //printf("输入圆桌上的人数n:");
person * head=initLink(n);
int k; k=1;//scanf("%d",&k); //printf("从第k人开始报数(k>1且k<%d):",n);
int m; scanf("%d",&m); //printf("数到m的人出列:");
findAndKillK(head, k, m);}
1859 翻转单词顺序
注意清空字符数组;同时,EOF的数值为-1,应当用%d而不是%c来判断
#include <stdio.h>
#include <string.h>
#define N 40
//1859 C 翻转句子中单词的顺序(栈和队列)
int main(){
char word[N], sentence[N][N]; int n, nums, i, j;
A:
while(scanf("%s", word)){
int len=strlen(word);
if(word[0]=='\"')
{for(i=0; i+1<len; i++) word[i]=word[i+1]; word[len-1]='\"';}
else if(word[len-1]=='\"')
{char temp[N]; strcpy(temp,word);
word[0]='\"'; for(i=1; i<len; i++) word[i]=temp[i-1];
strcpy(sentence[nums++], word); break;}
strcpy(sentence[nums++], word);
//if(word[len-1]=='\"') break;
}
n=nums;
for(i=n-1; i>0; i--) printf("%s ", sentence[i]);
printf("%s\n",sentence[0]);
for(i=0;i<N; i++)
for(j=0;j<N; j++)
sentence[i][j]='\0';
int d;
if(scanf("%d",&d)!=EOF) goto A;
else return 0;
}
1862 统计1出现的次数
//1862 F 在从1到n的正数中1出现的次数(栈和队列)
#include <stdio.h>
#define N 60
void count_1(int n, int res[]) {int cnt=0, i=0, k=0;
for(i=n; i>=0; i--) {
int flag=0;
int num=i;
while(num){
int r=num%10;
if(r==1) {cnt++; flag=1;}
num/=10;
}
if(flag==1) {res[k]=i; k++;}
}
printf("%d\n",cnt);
for(i=0; i<k; i++) printf("%d ",res[i]);
}
int main(){
int n, res[N]; scanf("%d",&n);
//int i=1; for(i=1; i<=n; i++) a[i]=i;
count_1(n,res); //长度
}
1863 加法分解 REF
(OJ有误还在检查,IS换成两个换行符就可以通过)
//1863 G 求整数的各个组合之和(栈和队列)
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define SEN 100
/*10
10
9 1
8 2
7 3
[7][2 1]这个有错误,应该把前面的也输出
6 4
[6][3 1]
5 4 1
4 3 2 1
*/
struct sqstack {char *base; char *top; int size;};
struct sqstack *initEmptyStack(){
struct sqstack *p;
p=(struct sqstack *)malloc(sizeof(struct sqstack));
if(p!=NULL){
p->base=(char *)malloc(sizeof(struct sqstack)*SEN);
if(p->base!=NULL)
{
p->top=p->base;
p->size=SEN;
return p;
}
}
else free(p);
}
void push(struct sqstack *p,int a) { *p->top++=a;}
void gettop(struct sqstack *p) {if(p->base!=p->top) return *(p->top-1); }
int pop(struct sqstack *p) {return *(--p->top);}
int main() {
struct sqstack *p1,*p2,*p3;
int m,t=1,a,sum,n; scanf("%d",&m);
p1=initEmptyStack(); //p1有序数列
p2=initEmptyStack(); //p2存储结果
p3=initEmptyStack(); //p3
printf("%d\n",m); n=m; //第一个
m--;
while(m--) {sum=0;
t=1; do {push(p1,t); t++;} while (t<=m+1); //m=7 876543 2 1
while(p1->base!=p1->top) {//依次对每个元素尝试
a=pop(p1); sum+=a; //printf("a=%d, sum=%d\n",a,sum);
if(sum>n) sum-=a; //如果加上一个元素超出了,不加
else if(sum==n) //如果加上一个元素刚好,再次分解p2
{//弹出p2存储到p3,
//printf("a=%d, sum=%d\n",a,sum);
while(p2->base!=p2->top) push(p3,pop(p2));
while(p3->base!=p3->top) printf("%d ",pop(p3));
printf("%d\n",a); sum-=a;
}
//如果加上一个元素还有空,要了,存到p2里面
else push(p2,a);
}
while(p2->base!=p2->top) pop(p2);
}
}
2597 括号匹配 (改了一下帅哥的代码)
//2597 E 括号匹配
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
ElementType ERROR = 142857;
typedef enum {FALSE, TRUE} Boolean;
typedef struct {
ElementType *data;
int top;
int maxSize;
} Stack;
//初始化操作,构造一个空栈
void InitStack(Stack *s, int maxSize){
s->data = (ElementType *)malloc(maxSize * sizeof(ElementType));
if (!s->data) exit(1);
s->top = -1;
s->maxSize = maxSize;}
//将栈清空
void ClearStack(Stack *s) {s->top = -1;}
//判断栈是否为空,若栈为空,则返回TRUE,否则返回FALSE
Boolean IsEmpty(Stack *s){
if (s->top == -1) return TRUE;
else return FALSE;}
//判断栈是否满,若栈满,则返回TRUE,否则返回FALSE
Boolean IsFull(Stack *s)
{if (s->top >= s->maxSize - 1) return TRUE; return FALSE;}
//入栈操作,若栈s不满,则插入元素e到栈中并成为新的栈顶元素,返回TRUE;否则返回FALSE
Boolean Push(Stack *s, ElementType e){
if (IsFull(s)) return FALSE;
s->top++;
s->data[s->top] = e;
return TRUE;}
//出栈操作,若栈s非空,则删除s的栈顶元素,并用e返回其值,返回TRUE;否则返回FALSE
Boolean Pop(Stack *s, ElementType *e){
if (IsEmpty(s)) return FALSE;
*e = s->data[s->top];
s->top--;
return TRUE;}
//获取栈顶元素,若栈s非空,则返回s的栈顶元素,栈顶指针保持不变;否则返回ERROR
ElementType GetTop(Stack *s){
if (IsEmpty(s)) return ERROR;
return s->data[s->top];}
//检验表达式中所含括号是否正确匹配,正确则返回TRUE,否则返回FALSE
Boolean ParenthesisMatchingChecker(char exp[]){
Stack s; ElementType e; int flag = 1; int i = 0; InitStack(&s, 100);
while (exp[i] != '\0' && flag){
switch (exp[i]){
case '(':
case '[':
case '{':Push(&s, exp[i]); break; //若是左括号压栈
case ')': //若是“)”,则根据当前栈顶元素的值分情况考虑
//若栈非空且栈顶元素是“(” //正确匹配,弹出栈顶元素
if (!IsEmpty(&s) && GetTop(&s) == '(') Pop(&s, &e);
else flag = 0; break; //否则,匹配失败,置标志位flag为0
case ']':
if (!IsEmpty(&s) && GetTop(&s) == '[') Pop(&s, &e);
else flag = 0; break;
case '}':
if (!IsEmpty(&s) && GetTop(&s) == '{') Pop(&s, &e);
else flag = 0; break;
}
i++; //继续读入下一个字符
}
if (IsEmpty(&s) && flag) return TRUE; //若栈空且标志位flag为1,则匹配成功,返回TRUE
else return FALSE; //否则匹配失败,返回FALSE
}
int main(){
int t; char c; scanf("%d%c",&t,&c);
while(t--){
char exp[1000]; scanf("%s", exp);
if (ParenthesisMatchingChecker(exp)) printf("Yes\n");
else printf("No\n");} }
1869 删除字符数组中的特定字符
#include <stdio.h>
#include <string.h>
#define N 100
int In(char a[], char e){int i=0, len=strlen(a);
for(i=0; i<len; i++) if(a[i]==e) return 1; return 0; }
//1869 B 在字符串中删除特定的字符(栈和队列)
//使用额外存储数组的这个方法比较容易出错
//前一个方法利用率缓冲输入输出的特征直接输出,对了
int main() {int i=0;
char a[N]; gets(a); int len_a=strlen(a);
char b[N]; gets(b); int len_b=strlen(b);
for(i=0; i<len_a; i++) if(!In(b,a[i])) putchar(a[i]);}
1858 两数之和为指定值
#include <stdio.h>
#define N 50
int main(){
int a[N], i=0, j=0; char temp;
while(scanf("%d%c",&a[i],&temp)) {i++; if(temp=='\n') break;}int n=i;
int sum; scanf("%d",&sum);
for(i=0; i<n; i++)
for(j=i+1; j<n; j++)
if(a[i]+a[j]==sum) {printf("%d %d",a[i],a[j]); break;}
//for(i=0; i<n; i++) printf("%d ",a[i]);}
//这题可能关键在于处理输入输出的问题,之前用的是scanfEOF,这里用的是%d%c判断
//要注意缓冲区系统的问题
1857 输出k个最小的数字
//1857 A 查找最小的k个元素(栈和队列)
//Len函数有时候有问题,还是直接带个长度参数进去吧
#include <stdio.h>
#define N 50
void Swap(int *a, int *b) {int t=*a; *a=*b; *b=t;}
void Sort(int a[], int n){
int i=0, j=0; for(i=0; i<n; i++)
for(j=0; j<n-1-i; j++)
if(a[j]>a[j+1]) Swap(&a[j], &a[j+1]);
}
int main(){
int n, k, a[N]; scanf("%d %d",&n, &k);
int i=0; for(i=0; i<n; i++) scanf("%d",&a[i]);
Sort(a,n); for(i=0; i<k; i++) printf("%d ",a[i]);
}
1878 Ackerman函数 REF
#include <stdio.h>
int Akm(int m, int n){
if(m==0) return n+1;
if(m!=0 && n==0) return Akm(m-1,1);
return Akm(m-1,Akm(m,n-1));
}
int main(){int m, n;
scanf("%d %d",&m,&n);
printf("%d", Akm(m,n));}
1871 丑数
//1871 D 丑数(栈和队列)
//只包含因子2、3和5
int isUgly(int a){
//int beauty=[5,7];
if(a%5==0) return 0;
if(a%7==0) return 0;
return 1;}
int main() {int n; scanf("%d", &n);
printf (isUgly(n) ? "YES":"NO");}
1860 第一个只出现一次的字符
#include <stdio.h>
#include <string.h>
#define N 40
void cnt_only(char a[]){
int i=0, j=0, len=strlen(a); //char b[N];
//只出现一次的 第一个
for(i=0; i<len; i++){ int cnt=0;//判断是否有重复
for(j=i+1; j<len; j++) if(a[i]==a[j]) cnt++;//有重复
//printf("a[%d]=%c, cnt=%d\n",i,a[i],cnt);
if(cnt==0) {printf("%c", a[i]); break;}}}
//1860 D 在字符串中查找第一次出现的字符(栈和队列)
int main(){char a[N]; gets(a); cnt_only(a);}
1868 A 调整数组顺序使奇数位于偶数前面(栈和队列)
int main() {int odds=0, evens=0;
int a[N]={0}, len_a=0, i=0; static int odd[N], even[N];
while(scanf("%d",&a[len_a])!=EOF) len_a++;
//printf("a:"); Prints(a);
for(i=0; i<len_a; i++)
if(isEven(a[i])){
even[evens]=a[i];
evens++;
}else{
odd[odds]=a[i];
odds++; }
//printf("odd:"); Prints(odd);
//printf("even:"); Prints(even);
Sort(odd); Sort(even);
Reverse(odd); Print(even);
}
懒狗模板:
//bokuwa_langou_des.h
#include <stdio.h>
#include <stdlib.h>
#define N 30
int Len(int a[]) {int len=0; while(a[len]!=0) len++; return len;}
void Swap(int *a, int *b) {int t=*a; *a=*b; *b=t;}
void Sort(int a[]){
int i=0, j=0, len=Len(a);
for(i=0; i<len; i++)
for(j=0; j<len-i-1; j++)
if(a[j]>a[j+1]) Swap(&a[j], &a[j+1]);}
void Clear(int a[]) {int i=0, n=Len(a);
for(i=0; i<n; i++) a[i]=0;}
void Reverse(int a[]) {int i=0, n=Len(a);
for(i=n-1; i>=0; i--) printf("%d ",a[i]);}
void Print(int a[]) {int i=0, len=Len(a);
if(len==0) return;
for(i=0; i<len; i++) printf("%d ",a[i]);}
void Prints(int a[]) {int i=0, len=Len(a);
if(len==0) {printf("\n"); return;}
for(i=0; i<len; i++) printf("%d ",a[i]);
printf("\n");}
int isEven(int a)
{if(a%2==0) return 1; else return 0;}
int Scanf_EOF(int a[]){ int len=0;
while(scanf("%d", &a[len])!=EOF) len++;
return len;}