题1:
#include<iostream>
using namespace std;
int main()
{
for(int i=1;i<=35;i++)
{
for(int j=1;j<=43;j++)
{
if(2.3*i*1.0+1.9*j*1.0==82.3&&j>i)
{
cout<<i<<" "<<j<<endl;
}
}
}
return 0;
}
题2:
#include<iostream>
using namespace std;
int s(int n)
{
if(n==1)
{
return 2;
}
else
{
return 2*s(n-1)-1;
}
}
int main()
{
int n;
cin>>n;
cout<<s(n);
return 0;
}
题3:
#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;
int ans=0;
void swap(char &a,char &b)
{
char temp;
temp=a;
a=b;
b=temp;
}
int cherk(char *s,int k,int i)
{
if(i>k)
{
for(int t=k;t<i;t++)
{
if(s[t]==s[i]) return 0;
}
}
return 1;
}
void array(char *s,int k,int n)
{
int sum=2;
if(k==n)
{
for(int i=0;i<n;i++)
{
if(s[i]=='a') sum=sum*2;
else if(s[i]=='b') sum=sum-1;
}
if(sum==0&&s[n-1]=='b')
{
ans++;
for(int i=0;i<n;i++)
cout<<s[i];
cout<<endl;
}
}
else
{
for(int i=k;i<n;i++)
{
if(cherk(s,k,i))
{
swap(s[i],s[k]);
array(s,k+1,n);
swap(s[i],s[k]);
}
}
}
}
int main()
{
int n;
cin>>n;
char *s=NULL;
s=(char*)malloc(sizeof(char)*n);
scanf("%s",s);
array(s,0,n);
cout<<ans;
free(s);
s=NULL;
return 0;
}
调用next_permutation(函数)
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int ans=0;
int main()
{
int n;
cin>>n;
getchar();
char s[n+5];
gets(s);
do{
int sum=2;
for(int i=0;i<n;i++)
{
if(s[i]=='a') sum=sum*2;
if(s[i]=='b') sum=sum-1;
}
if(sum==0&&s[n-1]=='b')
{
ans++;
for(int i=0;i<n;i++)
cout<<s[i];
cout<<endl;
}
}
while(next_permutation(s,s+n));
cout<<ans;
return 0;
}
李白打酒-深搜法
#include<iostream>
using namespace std;
int ans=0;
void def(int dian,int hua,int jiu)
{
if(dian==0&&hua==0&&jiu==1) ans++;
if(dian>0) def(dian-1,hua,jiu*2);
if(hua>0) def(dian,hua-1,jiu-1);
}
int main()
{
def(5,9,2);
cout<<ans;
}
题4:
#include<iostream>
#include<string.h>
using namespace std;
//计算个位
int ge_wei(int a)
{
if(a % 2 == 0)
return (a * 2) % 10;
else
return (a * 2 + 5) % 10;
}
//计算进位
int jin_wei(char* p)
{
char* level[] = {
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"
};
char buf[7];
buf[6] = '\0';
strncpy(buf,p,6);
int i;
for(i=5; i>=0; i--){
int r = strcmp(level[i], buf);
if(r<0) return i+1;
while(r==0){
p += 6;
strncpy(buf,p,6);
r = strcmp(level[i], buf);
if(r<0) return i+1;
return i;
}
}
return 0;
}
//多位数乘以7
void f(char* s)
{
int head = jin_wei(s);
if(head > 0) printf("%d", head);
char* p = s;
while(*p){
int a = (*p-'0');
int x = (ge_wei(a) + jin_wei(p+1)) % 10;
printf("%d",x);
p++;
}
printf("\n");
}
int main()
{
f("428571428571");
f("34553834937543");
return 0;
}
题5
#include<iostream>
using namespace std;
#define N 70
void f(char a[][N], int rank, int row, int col)
{
if(rank==1){
a[row][col] = '*';
return;
}
int w = 1;
int i;
for(i=0; i<rank-1; i++) w *= 2;
f(a, rank-1, row,col+w/2);
f(a, rank-1, row+w/2,col);
f(a, rank-1, row+w/2,col+w);
}
int main()
{
char a[N][N];
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++) a[i][j] = ' ';
f(a,6,0,0);
for(i=0; i<N; i++){
for(j=0; j<N; j++) printf("%c",a[i][j]);
printf("\n");
}
return 0;
}
题6-奇怪的分式:
辗转相除法求最大公约数
#include<iostream>
using namespace std;
int ans=0;
int gcd(int a,int b)//辗转相除法
{
if(b==0){
return a;
}
else{
return gcd(b,a%b);
}
}
int main()
{
for(int a=1;a<10;a++){
for(int b=1;b<10;b++){
if(a==b) continue;
for(int c=1;c<10;c++){
for(int d=1;d<10;d++){
if(c==d) continue;
int g1=gcd(a*c,b*d);
int g2=gcd(a*10+c,b*10+d);
if((a*c/g1==(a*10+c)/g2)&&((b*d/g1)==(b*10+d)/g2))
{
ans++;
}
}
}
}
}
cout<<ans;
return 0;
}
题7-六角填数 全排列,:
调用全排函数时,数组应该是有序的;
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int s[9]={2,4,5,6,7,9,10,11,12};
do
{
int r1=8+s[0]+s[1]+s[2];
int r2=3+s[2]+s[3]+s[5];
int r3=11+s[6]+s[8];
int r4=1+s[0]+s[7]+s[8];
int r5=1+s[3]+s[1]+s[4];
int r6=s[4]+s[5]+s[6]+s[7];
if(r1==r2&&r2==r3&&r3==r4&&r4==r5&&r5==r6)
{
printf("%d %d %d %d %d %d\n",r1,r2,r3,r4,r5,r6);
printf("%d\n",s[8]);
}
}
while(next_permutation(s,s+9));
return 0;
}
题8-蚂蚁感冒(不要模拟,注重思维)
提升之后的思维,应该是这样的
假想蚂蚁可以互相穿透身体,穿过感冒的蚂蚁身体时,会被感染感冒。
同方向的蚂蚁,且蚂蚁在感冒蚂蚁的前方,是不会被感染感冒的!
两种情况:
一:感冒的蚂蚁向右走;
- 在该蚂蚁的前方,且向左走的蚂蚁都会被感染感冒;
- 如果有蚂蚁曾穿透感冒的蚂蚁,则在感冒蚂蚁的后方,向右走的蚂蚁都会被感染感冒!
二:感冒的蚂蚁向左走
- 在蚂蚁的前方,且向右走的蚂蚁都会被感染感冒!
- 如果有蚂蚁曾穿透感冒的蚂蚁,则在感冒蚂蚁的后方,向左走的蚂蚁都会被感染感冒!
#include<iostream>
using namespace std;
int main()
{
int n,ans=1;
cin>>n;
int arr[n];
for(int i=0;i<n;i++) cin>>arr[i];
int x=arr[0];
if(x>0)
{//这只感冒蚂蚁向右走
for(int i=0;i<n;i++)
{//在蚂蚁的前方,且向左走
if(arr[i]<0&&-arr[i]>x) ans++;
}
if(ans!=1)
{//表示有向左走的蚂蚁穿过了第一只感冒的蚂蚁
for(int i;i<n;i++)
{
if(arr[i]>0&&arr[i]<x) ans++;
}
}
}
if(x<0)
{//这只感冒的蚂蚁向左走
for(int i=0;i<n;i++)
{//在蚂蚁左侧,向前走,会穿过蚂蚁而感冒
if(arr[i]>0&&arr[i]<-x) ans++;
}
if(ans!=1)
{
for(int i=0;i<n;i++)
{
if(arr[i]<0&&-arr[i]>-x) ans++;
}
}
}
cout<<ans;
return 0;
}
题-9-地宫夺宝
简单暴力的深搜-对60%
#include<iostream>
using namespace std;
long long ans;
const int MOD=1000000007;
int n,m,k;
int data[50][50];
void dfs(int x,int y,int max,int cnt)
{
if(x==n||y==m)
{
return;
}
int cur=data[x][y];
if(x==n-1&&y==m-1)
{
if(cnt==k||(cnt==k-1&&cur>max)){
ans++;
if(ans>MOD)
{
ans=ans%MOD;
}
}
}
if(cur>max)
{
dfs(x,y+1,cur,cnt+1);
dfs(x+1,y,cur,cnt+1);
}
dfs(x,y+1,max,cnt);
dfs(x+1,y,max,cnt);
}
int main()
{
cin>>n>>m>>k;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>data[i][j];
}
}
dfs(0,0,-1,0);
cout<<ans;
return 0;
}
动态规划
#include<iostream>
#include<string.h>
using namespace std;
int n,m,k;
int data[50][50];
long long ans=0;
const int MOD=1000000007;
long long cache[50][50][14][13];
long long dfs(int x,int y,int max,int cnt)//表示状态,如果有相同的状态,直接调用
{
if(cache[x][y][max+1][cnt]!=-1)
return cache[x][y][max+1][cnt];
if(x==n||y==m||cnt>k)
return 0; //不符合条件,直接剪枝
int cur=data[x][y];
long long ans=0;//每次都初始值为1
if(x==n-1&&y==m-1) //出口
{ //达到出口,手中的宝物数恰好为k件,或手中的件数虽为k-1,但是可以取最后一件宝物
if(cnt==k||cnt==k-1&&cur>max) ans=1;
return ans;
}
if(cur>max)//拿走当前宝物的情况
{
ans=ans+dfs(x,y+1,cur,cnt+1);
ans=ans+dfs(x+1,y,cur,cnt+1);
} //不拿走当前宝物的情况
ans=ans+dfs(x,y+1,max,cnt);//记忆满足条件的数量
ans=ans+dfs(x+1,y,max,cnt);
cache[x][y][max+1][cnt]=ans%MOD;//取模
return cache[x][y][max+1][cnt];
}
int main()
{
cin>>n>>m>>k;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>data[i][j];
}
}
memset(cache,-1,sizeof(cache));//初始化,宝藏的价值为-1,不能为零
cout<<dfs(0,0,-1,0);
return 0;
}
题-10 小朋友排排队
树状数组
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int lowbit(int n)//二进制最小的数
{
return n - (n & (n - 1));
}//n为边界,i为查询的数,v增量,c为数组
void updata(int n, int i, int v, int c[]) //更新树状数组
{
for (int k = i; k <= n; k += lowbit(k))
{
c[k] += v;
}
}
int getSum(int c[], int i) //求和的
{
int sum = 0;
for (int k = i; k >= 1; k -= lowbit(k))
{
sum += c[k];
}
return sum;
}
int h[100000];//小朋友的身高
long long cnt[100000];//存取交换的次数
int c[1000000 + 1];//树状数组
int main()
{
int n;
scanf("%d", &n);
int maxH = -1;
for (int i = 0; i < n; ++i)
{
scanf("%d", &h[i]);
if (h[i] > maxH)maxH = h[i];
}
for (int i = 0; i < n; ++i) //从左到右求出有没有比这个值高的
{
updata(maxH + 1, h[i] + 1, 1, c);
int sum = getSum(c, h[i] + 1);
cnt[i] += (i + 1) - sum;
}
memset(c, 0, sizeof(c));
for (int i = n - 1; i >= 0; --i)//从右向左
{
updata(maxH + 1, h[i] + 1, 1, c);
cnt[i] += getSum(c, h[i]);
}
long long ans = 0;
for (int i = 0; i < n; ++i) //求和
{
ans += (cnt[i] * (cnt[i] + 1) / 2);
}
printf("%lli\n", ans);
return 0;
}