编写算法,打印具有下面规律的图形。
1
5 2
8 6 3
10 9 7 4
输入
输入有多组,每组一行,只有一个整数n(0<n<25)。
输出
按照指定格式输出。每组之间有一个空行。
样例输入 复制
1
4
样例输出 复制
1
1
5 2
8 6 3
10 9 7 4
思路:
1.n有几行,就有几行
2.第i行就有i个
先反着输入,最后倒叙输出;
#include <iostream>
using namespace std;
int main(){
int a[30][30]={0};
int n;
int first=1;
while(cin>>n){
if(first){
first=0;
}
else{
cout<<endl;
}
int num=1;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
a[j][i]=num;
num++;
}
}
for(int col=1;col<=n;col++){
for(int lie=col;lie>0;lie--){
cout<<a[col][lie]<<" ";
}
cout<<endl;
}
}
}
1
2 5
3 6 8
4 7 9 10
求阶乘
#include <iostream>
using namespace std;
#include <cmath>
#include <iomanip>
int main(){
int n;
while(cin>>n){
double sum=1.0;
long long f=1;//计算阶乘
int sign=-1;//控制符号
for(int i=2;i<=n;i++){
f=f*(2*i-1)*(2*i-2);
sum=sum+1.0/f*1.0*sign;
sign=-sign;
}
cout<<fixed<<setprecision(5)<<sum<<endl;
}
}
吃桃子
#include <iostream>
using namespace std;
int peach(int m,int k){
if(m==1) return k;
else
return peach(m-1,2*(k+1));
}
int main(){
int n;
int m,k;
cin>>n;
while(n--){
cin>>m>>k;
cout<<peach(m,k)<<endl;
}
}
#include <iostream>
using namespace std;
int main(){
int n;
int m,k;
cin>>n;
while(n--){
cin>>m>>k;
for(int i=1;i<m;i++){
k=2*(k+1);
}
cout<<k<<endl;
}
}
选票
#include <iostream>
using namespace std;
#include <cstring>
int main(){
int a[6]={0};
int n;
while(cin>>n){
if(n==0)
break;
else if(n==-1){
for(int i=1;i<=5;i++){
cout<<i<<" number get "<<a[i]<<" votes"<<endl;
}
cout<<endl;
memset(a,0,sizeof(a));
}
else{
a[n]++;
}
}
}
注意:1.如果要使用memset(a,0,sizeof(a));
加头文件<cstring>
翻译数字
#include <iostream>
using namespace std;
#include <string>
int main(){
string res[11]={"zero","one","two","three","four","five","six","seven","eight","nine"};
string n,ans;
while(cin>>n){
int len=n.length();
for(int i=0;i<len-1;i++)
cout<<res[n[i]-'0']<<"-";
cout<<res[n[len-1]-'0'];
cout<<endl;
}
}
判断相同
#include <iostream>
using namespace std;
#include <string>
#include <cstring>
int main(){
int n;
int a[110]={0};
int now;
int flag=0;//是否找到
while(cin>>n){
flag=0;
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
cin>>now;
a[now]++;
}
for(int i=1;i<=100;i++){
if(a[i]>1){
flag=1;
break;
}
}
if(flag==1)
cout<<"repeat"<<endl;
else
cout<<"No repeat"<<endl;
}
}
鸡兔同笼
#include <iostream>
#include <string>
using namespace std;
int main(){
int c,r;
int n;
cin>>n;
int a;
while(n--){
cin>>a;
int minnum=a;
int maxnum=0;
if(a%2!=0){
cout<<"0 0"<<endl;
}
else{
for(int c=1;c<=a/2;c++){
r=(a-2*c)/4;
if(r+c>maxnum)
maxnum=r+c;
if(r+c<minnum)
minnum=r+c;
}
cout<<minnum<<" "<<maxnum<<endl;
}
}
}
约瑟夫问题
1.用循环实现,剩余的猴子数来作为循环条件
用current报数,顺时针移动
找到第m个,remaining--,往下走一个
#include <iostream>
#include <cstring>
using namespace std;
int yue(int n,int m){
int remaining=n;
int a[301];
int cur=0;
memset(a,1,sizeof(a));
while(remaining>1){
int cnt=0;//报数
while(cnt<m){
if(a[cur]){
cnt++;
}
if(cnt<m)
{
cur=(cur+1)%n;
}
}
//报到m了
a[cur]=0;
remaining--;
cur=(cur+1)%n;
//报到出局了
while(!a[cur]){
cur=(cur+1)%n;
}
}
for(int i=0;i<n;i++){
if(a[i]){
return i+1;
}
}
return -1;
}
int main(){
int m,n;
int monkey[301];
while(cin>>n>>m){
if(m==0&&n==0)
break;
cout<<yue(n,m)<<endl;
}
}
给余猜数(模拟)
#include <iostream>
using namespace std;
int main(){
int m,n,k;
while(cin>>m>>n>>k){
for(int i=1;i<=100;i++){
if(i%3==m&&i%5==n&&i%7==k){
cout<<i<<endl;
}
}
}
}
n*n方阵
#include <iostream>
using namespace std;
int main(){
int n;
int a[100][100]={0};
while(cin>>n){
int t;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==j)
{
a[i][j]=0;
}
else if((i>j)&&(i+j!=n-1)){
if(i+j<n-1){
a[i][j]=2;
}
else{
a[i][j]=3;
}
}
else if(i+j==n-1){
a[i][j]=0;
}
else{
if(i+j<n-1){
a[i][j]=1;
}
else {
a[i][j]=4;
}
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
}
看和说
#include <iostream>
using namespace std;
#include <string>
int main(){
int n;
cin>>n;
string s;
while(n--){
cin>>s;
int num=1;
for(int i=0;i<s.length()-1;i++){
if(s[i]==s[i+1]){
num++;
}
else{
cout<<num<<s[i];
num=1;
}
}
cout<<num<<s[s.length()-1]<<endl;
}
}
醉酒的狱卒
#include <iostream>
using namespace std;
#include <vector>
int main(){
int t;
int n;
int cnt;
cin>>t;
while(t--){
cin>>n;
vector<int> a(n+1);
cnt=0;
for(int i=1;i<=n;i++){
a[i]=1; //第一轮门打开了,1为开
}
for(int i=2;i<=n;i++){
for(int j=i;j<=n;j=j+i){
a[j]=!a[j];
}
}
for(int i=1;i<=n;i++){
if(a[i])
cnt++;
}
cout<<cnt<<endl;
}
}
杨辉三角
思路:第一列加对角线为1;
其余相加
#include <stdio.h>
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int a[n][n]={0};
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){
if(j==0||i==j){
a[i][j]=1;
}
else{
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
printf("%d",a[i][j]);
if(i!=j)
printf(" ");
}
printf("\n");
}
}
printf("\n");
}
合并
#include <iostream>
using namespace std;
#include <vector>
int main(){
int x;
while(true){
vector<int> A,B,C;//每次清空
while(cin>>x){
if(x==-1)
break;
A.push_back(x);
}
while(cin>>x){
if(x==-1)
break;
B.push_back(x);
}
int i=0,j=0;
if(A.empty()&&B.empty)
break;
while(i<A.size()&&j<B.size()){
if(A[i]<=B[j]){
C.push_back(A[i++]);
}
else{
C.push_back(B[j++]);
}
}
while(i<A.size()){
C.push_back(A[i++]);
}
while(j<B.size()){
C.push_back(B[j++]);
}
for(int i=0;i<C.size();i++){
cout<<C[i];
}
cout<<endl;
}
}
汉诺塔
思路:
n==1 调用move函数输出move(x,y)
else 借用第三个杆,把n-1个盘子移到第二个
move
n-1个盘子借用a,移到c
整数划分
#include <iostream>
using namespace std;
int ans(int n,int m){
if((n<1)||(m<1))
return 0;
if(n==1||m==1)
return 1;
if(n<m)
return ans(n,n);
if(n==m)
return 1+ans(n,m-1);
if(n>m)
return ans(n,m-1)+ans(n-m,m);
}
int main(){
int n;
while(cin>>n)
cout<<ans(n,n)<<endl;
}
开关灯
思路:1,最后的状态有两种情况
0101010101010101010101..........
或者10101010101010101010..........................
对比改变次数
取最小
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
int main(){
int n;
while(cin>>n){
int cnt1=0,cnt2=0;
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
//情况1 0101010101....
for(int i=0;i<n;i++){
if(i%2==0){
if(a[i]!=0){
cnt1++;
}
}
else{
if(a[i]!=1)
cnt1++;
}
}
for(int i=0;i<n;i++){
if(i%2==0){
if(a[i]!=1){
cnt2++;
}
}
else{
if(a[i]!=0)
cnt2++;
}
}
cout<<min(cnt1,cnt2)<<endl;
}
}
&的用法
1.&按引用传递,不是按值传递,避免了拷贝,提高了性能
2.如果不加&,函数调用时会被拷贝一份,原来的数不会改变
最大的子段和
思路:1.设置一个cursub=a[0],maxsub=a[0];
2.cursub=max(a[i],a[i]+cursub);
maxsub=max(maxsub,cursub);
众数(自己做出来)
#include <iostream>
using namespace std;
#include <vector>
int main(){
int n;
cin>>n;
while(n--){
int m;
cin>>m;
int maxnum=0;
vector<int> a(m);
for(int i=0;i<m;i++){
cin>>a[i];
if(maxnum<a[i]){
maxnum=a[i];
}
}
vector<int> cnt(maxnum+1,0);
for(int i=0;i<m;i++){
cnt[a[i]]++;
}
int maxres=0;
int j=0;
for(j=0;j<=maxnum;j++){
if(cnt[j]>maxres){
maxres=j;
}
}
cout<<maxres<<" "<<cnt[]<<endl;
}
}
矩阵乘法
1.思路!!!!:计算公式:c[i][j]=a[i][k]*b[k][j];三重循环
2.注意二维数组
如何定义
vector<vector<int>> a(n,vector<int>(n))
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n;
while(cin>>n){
vector<vector<int>> a(n,vector<int>(n));
vector<vector<int>> b(n,vector<int>(n));
vector<vector<int>> c(n,vector<int>(n));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>b[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
c[i][j]=0;
for(int k=0;k<n;k++){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<c[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
}
最大子段和
思路:
1.用二维矩阵记录
遍历数组:
如果相同, res[i][j]=res[i-1][j-1]+1;
如果不同res[i][j]=max(res[i-1][j],res[i][j-1]);
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
int main(){
string a,b;
while(cin>>a>>b){
int m=a.length();
int n=b.length();
vector<vector<int>> res(m+1,vector<int>(n+1));
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(a[i-1]==b[j-1]){
res[i][j]=res[i-1][j-1]+1;
}
else{
res[i][j]=max(res[i-1][j],res[i][j-1]);
}
}
}
cout<<res[m][n]<<endl;
}
}
找零钱
思路:1.要求从5分最多的情况看,只输出一组,借助flag标记是否找到
#include <iostream>
using namespace std;
int main(){
int n;
int flag;//标记第一组是否找到
while(cin>>n){
flag=0;
for(int x=n/5;x>=1;x--){
for(int y=(n-5*x)/2;y>=1;y--){
int z=n-5*x-2*y;
if(z>=1){
cout<<x<<" "<<y<<" "<<z<<endl;
flag=1;
break;
}
}
if(flag==1)
break;
}
}
}