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
#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;
}