西工大上级2015年前整理

2015六数码
2015输出命题公式的真值表
2015连阴雨
2014木乃依一迷宫
2014滑雪不会
2012 数独不会
2010 最长子序列
2010 装载问题
2010灌溉问题
2009N皇后和求边长
2009奶牛飞盘

2014_1121猴子挖花生

在这里插入图片描述
解题分析:/*
算法思想:
怎么计算路径?
其实用目标点的横坐标和纵坐标减去初始点的横纵坐标,然后循环进行同样的操作,就可以算出路径了
o点到A的距离其实就是,(A的横坐标-o的横坐标)+(A的纵坐标-o的纵坐标)
再重复A到B,B到C。。。。。。。
*/
在这里插入图片描述

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

int main()
{
    int n;
    cin>>n;
    vector<int> v,r;
    int x =0,y =0;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        v.push_back(x);
        r.push_back(y);
    }
    int sum =0,a=0,b=0;
    int j;
    for(j=0;j<n;j++)
    {
        sum += abs(v[j]-a);
        sum += abs(r[j]-b);
        a = v[j];
        b = r[j];
    }
    sum += abs(a-0);
    sum += abs(a-0);
    cout<<sum;
    return 0;
}

2012年Tom和jerry吃花生米

在这里插入图片描述
解题思路:
花生米的数量n是不确定的,jerry每次拿K粒,要使Tom吃到最后一粒花生米,Tom要在偶数次(j)吃到则k*j >=n

#include <iostream>
#include <vector>

using namespace std;

int getk(int n) //使用列举的方法,找到k,
{
    int k,j;//j表示取的次数,每次是两人一个回合,所以j+2,k表示jerry每次拿的数量
    for(j=2;j<1000;j=j+2)//j为回合
    {
        for(k=1;k<=10;k++)
        {
            if(n==1) return 0;//表示jerry让Tom 先拿
            if(k*j>=n) return k; //表示n粒花生米,最后被Tom拿完
        }
    }
}
int main()
{
    int  n;
    vector<int> v;
    cin>>n;
    for(int i=0;n != 0;i++)
    {
       v.push_back(n);
       cin>>n;
    }
    for(int i=0;i<v.size();i++)
    {
        cout<<getk(v[i]);
        if(i != (v.size()-1))
        {
            cout<<endl;
        }
    }
    return 0;
}

在这里插入图片描述
花生米(二)
在这里插入图片描述

#include <iostream>

using namespace std;

int status[1001];

void Search()
{
    for(int i = 1; i <= 10; i++) //当i为10时,若A先取(1或5),剩下必然为奇数,剩下奇数等价于让B先取
    {
        if(i % 2 == 0) 
            status[i] = 1;
        else
            status[i] = 0;
    }

    for(int i = 11; i <= 1000; i++)
    {
        if(status[i-1]  && status[i-5]  && status[i-10] )//当jerry要取最后一个花生米时,Tom先取
            status[i] = 0;
        else //否则,Tom先取
            status[i] = 1;

    }
}

int main()
{
    Search();
    int n;
    while(cin >> n && n)
        cout << status[n] << endl;
}

2012年计算后缀表达式
在这里插入图片描述

#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
int cal(int a,int b, char op)
{
        switch(op)
        {
            case '+': return a+b;
            case '-': return a-b;
            case '*': return a*b;
            case '/': return a/b;
        }
        return 0;
}
int add(char s[])
{
    stack<int> ss;
    int a,b;
    for(int i=0;s[i]!='\0';i++)
    {
        if(s[i]>=48&&s[i]<=57)
        {
            ss.push(s[i]-'0');
        }
        else
        {
              a = ss.top();
              ss.pop();
              b = ss.top();
              ss.pop();
              ss.push(cal(a,b,s[i]));
        }
    }
    return ss.top();
}
int main()
{
    char str[100];
    char *s = str;
    cin>>str;
    cout<<add(s);
    return 0;
}

在这里插入图片描述
2012柱状图
在这里插入图片描述

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    int a[100]={0};
    char s[80];
    int l1,l2;
    for(int i=0;i<4;i++)
    {
        gets(s);
        l2 = strlen(s);
        for(int j=0;j<l2;j++)
        {
            if('A'<=s[j]&&s[j]<='Z')
            {
                  a[s[j]]++;
            }
        }
    }
    l1 = 'A';l2 = 'Z';
    int h=0; //获得最高的哪个值
    for(int i=l1;i<l2;i++)
    {
        if(a[i]>h)
            h = a[i];
    }
    while(h)
    {
        int d = 0;
        for(int j=l1;j<=l2;j++)
        {
            if(a[j]>=h)
                d = j;  //d获得每行的最右边*的位置
        }
        for(int j=l1;j<=l2;j++)
        {
            if(a[j]>=h)//只有m[j]>=h才有资格输出
                if(j<d)
                    cout<<"* ";
                else
                    cout<<"*";//最右边不多空格
            else
                if(j<d)
                cout<<"  ";
        }
        cout<<endl;
        h--;
    }
    cout<<"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    return 0;
}

在这里插入图片描述

[重点]2011年 将数分解成Fibonacci数之和
思路:先获得一个有FBNQ数组
再根据所给定的值,从大往小遍历,输出FBNQ之和

#include <iostream>
using namespace std;
int FBNQ[22]={0};
void getFBNQ()
{
    FBNQ[1] = 1;
    FBNQ[2] = 1;
    for(int i=3;i<22;i++)
    {
        FBNQ[i] = FBNQ[i-1] + FBNQ[i-2];
    }
}
bool IsFBNQ(int n)
{
    for(int i=1;i<22;i++)
    {
        if(n == FBNQ[i])
        {
            return true;
        }
    }
    return false;
}
int main()
{
    getFBNQ();
    int n;

    while(cin>>n && n)
    {
        int flag = 0;
         while(n)
        {

            for(int i=21;i>=1;i--)
            {
                if(FBNQ[i]<=n)
                {
                    if(flag) cout<<"+";
                    cout<<FBNQ[i];
                    flag = 1;
                    n = n - FBNQ[i];
                    break;
                }
            }
        }
        cout<<endl;
    }
    return 0;
}

在这里插入图片描述
201102 打印杨辉三角形
打印杨辉三角形。在标准输入上按照如下格式打印杨辉三角形的前K(<=9)
打印如下:

               1
            1     1
         1     2     1
      1     3     3     1
   1     4     6     4     1
1     5     10    10    5     1

算法思想,
第一步,要计算出直角三角形矩阵,直角三角形矩阵
从第二行开始,除了每一行的第一个和最后一个为1
其它值与上一行的关系为:a[i][j] = a[i-1][j-1] + a[i-1][j]

输出直角矩阵为 0…i

扫描二维码关注公众号,回复: 10278253 查看本文章
#include <stdio.h>zhijiao
int main()
{
    int n;
    scanf("%d",&n);

    int a[n][n];

    for(int i=0;i<n;i++)
    {
        a[i][0] = 1;
        a[i][i] = 1;
        for(int j = 1;j<i;j++)
        {
            a[i][j] = a[i-1][j-1] + a[i-1][j];
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n-i-1;j++)
        {
            printf("   ");
        }
        for(int j =0;j<=i;j++)
        {
            printf("%-6d",a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

在这里插入图片描述

201103 调换主元
从F盘的a.txt中重复地读入一个N(<=10)阶方阵A(A所有元素为正整数),对A做如下操作:
a)将A第一列中最大数所在的行与第一行对调;
b)将A第二列中从第二行到第N行中最大数所在的行与第二行对调;
c)… … … … … … …
d)将A第N - 1列中从第N - 1行到第N行中最大数所在的行与第N - 1行对调。
e)输处调整后的矩阵
输入:每组数据的第一行为一正整数n(<= 10),后跟n行数据,每行n个正整数(用空格隔开)。若n = 0,则表示输出结束,程序终止。
输出:将每组数据所表示的矩阵调整后输出。

a.txt数据如下图所示:
在这里插入图片描述

#include <iostream>
#include <fstream>
using namespace std;

const int n = 5;
int a[n][n]={0};

void Init(int n) //从F盘下的a.txt文件中,将数据读入到数组a[n][n]中
{
    ifstream in("F://a.txt");
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            in>>a[i][j];
        }
    }
}
void exchange(int i,int j)//交换第i行和第j行
{
    for(int k=0;k<n;k++)
    {
        int temp = a[i][k];
        a[i][k]  = a[j][k];
        a[j][k]  = temp;
    }
}

int main()
{
    int ma = 0;
    int maxC = 0;
    Init(n);
    for(int j=0;j<n;j++)
    {
        ma = 0;
        for(int i=j;i<n;i++)
        {
            if(a[i][j]>ma)
            {
                ma = a[i][j];
                maxC = i;
            }
        }
        exchange(j,maxC);
    }

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

运行如下:
在这里插入图片描述
201104 合并字符串

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    string str[2];//分别为S1,S2
    cin>>str[0];
    cin>>str[1];
    int i=0,j=0;
    int len = str[0].length()+str[1].length();//取得两串长度
    char ss[len]; //作为合并之后的数组
    int k; 
    j = str[1].length()-1;//S2串从后往前
    k=0;
    while(i<str[0].length()&&j>=0)//当两串还不为空时
    {
        if(k%2 == 0 )
        {
            ss[k++]= str[0][i++];
        }
        else
        {
            ss[k++]= str[1][j--];
        }
    }
    if(i<str[0].length())//S2串用完了
    {
        for(;i<str[0].length();i++)
        {
            ss[k++]= str[0][i];
        }
    }
    if(j>=0)//S1串用完了
    {
        for(;j>=0;j--)
        {
            ss[k++]= str[1][j];
        }
    }
    ss[k] = '\0';
    cout<<ss;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
201105 完成多项式的加法运算
算法思想:每一个多项式用两个栈表示,一个放系数,一个放指数
循环:(直至两栈都为空)
比较指数栈的top,相同系数相加
否则将指数小的,压入到新的系数栈和指数栈中

#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
int main()
{
    ifstream in("F:\\a.txt");
    int total;
    //num[0],num[1],num[2]分别表示第一,第二,结果的系数
    stack<int> num[3];
    //power[0],power[1],power[2]分别表示第一,第二,结果的指数
    stack<int> power[3];
    int temp;
    for(int j=0;j<2;j++) //将数据压入栈中
    {
        in>>total;//有几个多项式
        for(int i = 0;i<total;i++)
        {
            in>>temp;
            num[j].push(temp);
            in>>temp;
            power[j].push(temp);
        }
    }
    while((!num[1].empty())&&(!num[0].empty()))
    {
       if(power[0].top() == power[1].top())
       {
           num[2].push(num[0].top()+num[1].top());
           power[2].push(power[0].top());
           num[1].pop();
           num[0].pop();
           power[0].pop();
           power[1].pop();
       }
       else if(power[0].top() > power[1].top())
       {
            num[2].push(num[1].top());
            power[2].push(power[1].top());
            num[1].pop();
            power[1].pop();
       }
       else
       {
            num[2].push(num[0].top());
            power[2].push(power[0].top());
            num[0].pop();
            power[0].pop();
       }
    }
    while(!num[1].empty())
    {
        num[2].push(num[1].top());
        num[1].pop();
        power[2].push(power[1].top());
        power[1].pop();
    }
    while(!num[0].empty())
    {
        num[2].push(num[0].top());
        num[0].pop();
        power[2].push(power[0].top());
        power[0].pop();
    }
    while(!num[2].empty())
    {
        cout<<num[2].top()<<" ";
        num[2].pop();
        cout<<power[2].top()<<" ";
        power[2].pop();
    }
    return 0;
}

201001 火星问题
难点:读懂几句话
什么是?A+B 等于小于A的最大3的倍数与B的和
即为A+B = (比A小的但又是3倍数,这个数最接近A)
比如 A= 8,则该数为6

#include <iostream>
using namespace std;
int main()
{
    int A,B;
    cin>>A;
    cin>>B;
    if(A%3==0  && B%5 ==0)
    {
        cout<<A+B;
    }
    else if(A%3 && B%5 == 0)
    {
        cout<<(A-A%3+B);
    }
    else if(A%3 ==0 && B%5)
    {
        cout<<A+ (5-B%5)+B;
    }
    else
    {
        cout<<(A-A%3+B)+A+ (5-B%5)+B;
    }
    return 0;
}

2009 约瑟夫问题
#include <iostream>
/*
思路:
循环遍历1~N,用变量t表示(当只剩下一个没被点到的数为止。)
如果t = N时,t = 0
用一个变量y表示几个数一循环,
if y从1开始,每次数(判断该数没有被点到过,就自增)到10,
当到10时,置为0
最后输出
*/
using namespace std;

int main()
{
    int N,M;
    cin>>N>>M;
    int temp = N;
    int a[N] = {0};
    int y =0;
    for(int i=1;temp != 1;i++)
    {
        if(a[i]!=1)
            y++;
        if(y == M)
        {
            a[i] = 1;
            y = 0;
            temp--;
        }
        if(i == N)
            i = 0;
    }
    for(int i=1;i<=N;i++)
    {
        if(!a[i])
            cout<<i;
    }
    return 0;
}

2009合并有序数组

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

int main()
{
    vector<int> a,b,c;
    int n,m;
    cin>>n;
    int t;
    for(int i=0;i<n;i++)
    {
        cin>>t;
        a.push_back(t);
    }
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>t;
        b.push_back(t);
    }
    for(int i=0;i<b.size();i++)
    {
        a.push_back(b[i]);
    }
    sort(a.begin(),a.end());
    for(auto it=a.begin();it != a.end();it++)
        cout<<*it<<endl;
    return 0;
}
发布了110 篇原创文章 · 获赞 14 · 访问量 6005

猜你喜欢

转载自blog.csdn.net/qq_38173631/article/details/104663634