题记:若立志投身算法研究,可精研理论算法:动态规划、递归、深度搜索等;若以解决问题为目的,主要为了工作内容,当尝试快而简单的方法,这该是学习的本意。
简单难度之二
1.字符串排序
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n=0; cin>>n;
string str;
vector<string> vec;
while(cin>>str) vec.push_back(str);
sort(vec.begin(), vec.end());
for(string s : vec) cout<<s<<endl;
return 0;
}
//
int main() {
int n;
string text;
vector<string> vec;
cin>>n;
cin.get(); //这里容易出错,输入数字后我们按下回车,在输入字符串之前,要将键盘缓冲器的换行符读取出来
for(int i=0;i<n;i++) {
getline(cin, text);
vec.push_back(text);
}
sort(vec.begin(), vec.end());
for(int i=0;i<vec.size();i++) {
cout<<vec[i]<<endl;
}
return 0;
}
2.求int型正整数在内存中存储时1的个数
#include<bitset>
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
bitset<32> b(n);
cout<<b.count();
}
//
int main()
{
int n;
cin>>n;
int m=0;
while(n)
{
m+=n%2;
n/=2;
}
cout<<m;
}
3.简单密码
#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main() {
string s;
unordered_map<char, char> map;
map['a'] = '2'; map['b'] = '2'; map['c'] = '2';
map['d'] = '3'; map['e'] = '3'; map['f'] = '3';
map['g'] = '4'; map['h'] = '4'; map['i'] = '4';
map['j'] = '5'; map['k'] = '5'; map['l'] = '5';
map['m'] = '6'; map['n'] = '6'; map['o'] = '6';
map['p'] = '7'; map['q'] = '7'; map['r'] = '7'; map['s'] = '7';
map['t'] = '8'; map['u'] = '8'; map['v'] = '8';
map['w'] = '9'; map['x'] = '9'; map['y'] = '9'; map['z'] = '9';
while (getline(cin, s)) {
int len = s.size();
for (int i = 0; i < len; ++i) {
if (s[i] >= 'A' && s[i] < 'Z') {
s[i] = s[i] - 'A' + 'a' + 1;
continue;
} else if (s[i] == 'Z') {
s[i] = 'a';
continue;
} else if (s[i] >= 'a' && s[i] <= 'z') {
s[i] = map[s[i]];
continue;
}
}
cout << s << endl;
}
return 0;
}
//
int main()
{
string input;
while(cin>>input)
{
int length = input.length();
for(int i=0; i<length; i++)
{
//数字
if(input[i]-'0'>=0 &&input[i]-'9'<=0)
{
cout<<input[i];
}
//大写字母
else if(input[i]-'A'>=0 &&input[i]-'Z'<0)
{
input[i] = input[i]+33;
cout<<input[i];
}
else if(input[i]-'Z'==0)
{
cout<<"a";
}
//小写字母
else if(input[i]-'a'>=0 &&input[i]-'s'<0)
{
cout<<(input[i]-'a')/3+2;
}
else if(input[i]-'s'==0)
{
cout<<7;
}
else if(input[i]-'s'>0 &&input[i]-'w'<0)
{
cout<<8;
}
else if(input[i]-'v'>0 &&input[i]-'z'<=0)
{
cout<<9;
}
}
cout<<endl;
}
return 0;
}
4.汽水瓶
#include<iostream>
using namespace std;
//最多可喝的汽水瓶数的函数接口
int Soda_Bottle_Num(int num)
{
int sum = 0; //计数器,最多可以喝的汽水瓶数
int count = 0; //计数器。每一次空瓶换汽水操作可以喝到的汽水瓶数
// 空汽水瓶数小于或等于 1 时,无法喝到汽水,也无法通过“先借后还”方式喝到汽水
if (num <= 1)
{
sum += 0;
}
// 空汽水瓶数大于或等于 2 时,至少可以喝到一瓶汽水,如通过“先借后还”方式就可以喝到汽水
while (num >= 2)
{
num += 1; //只要手上的空汽水瓶数大于或等于2,不论情况如何,先借一个空汽水瓶
count = num / 3; //一次空汽水瓶换汽水操作后可以喝到的汽水瓶数(3 个空汽水瓶换 1 瓶汽水,喝它!)
num = num % 3 + count - 1; //剩下的空汽水瓶数,包括之前没换的空汽水瓶 + 喝完汽水后的空汽水瓶 + 要还回去空汽水瓶(之前借了一个空汽水瓶);
sum += count; //累计可以喝到的汽水瓶数
}
return sum; //返回最多可以喝的汽水瓶数
}
//主函数
int main()
{
int n;
while(cin >> n) //输入测试数据
{
if(n != 0)
{
cout << Soda_Bottle_Num(n) << endl; //输出结果
}
}
return 0;
}
//更简单的方法:注意到每两个空汽水瓶就可以通过借一个空汽水瓶来喝到一瓶汽水,故最多可以喝到的汽水瓶数等于空汽水瓶数除以二,即 sum = num / 2
//
int main () {
int n;
while (cin >> n) {
int ans = 0;
if (n == 0) {
break;
}
while (n >= 3) {
ans += n / 3;
n = n / 3 + n % 3;
}
if (n == 2) {
ans++;
}
cout << ans << endl;
}
return 0;
}
5.删除字符串中出现次数最少的字符
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
while(cin>>s)
{
vector<int> c(26,0);
for(auto i:s) c[i-'a']++;
int m=c[s[0]-'a'];
for(int i=0;i<26;i++)
if(c[i]) m=min(m,c[i]);
for(auto i:s)
if(c[i-'a']>m) cout<<i;
}
}
6.单词倒排
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<string> str(100);
int j = 0;
string ss;
getline(cin, ss);
for(int i = 0; i < ss.size(); ++i){
if(!isalpha(ss[i]))
continue;
while(isalpha(ss[i]))
str[j] += ss[i++];
j++;
}
for(int i = j - 1; i >= 0; --i)
cout << str[i] << ' ';
}
7.图片整理
#include<bits/stdc++.h>
using namespace std;
int main(){
string str;
multiset<char> st;
while(cin>>str){
for(int i=0;i<str.size();i++){
st.insert(str[i]);
}
for(auto s:st){
cout<<s;
}
cout<<endl;
}
return 0;
}
//
int main(){
string str;
while(cin>>str){
sort(str.begin(),str.end());
cout<<str<<endl;;
}
return 0;
}
7.蛇形矩阵
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
//填表 参考了题解
while(cin>>n){
vector<vector<int>> vec(n,vector<int>(n,0));
int num=1;
for(int i=0;i<n;++i){
int j=i;
int k=0;
while(j>=0){
vec[j][k]=num++;
j--;
k++;
}
}
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
if(vec[i][j]!=0){
cout<<vec[i][j]<<" ";
}else
break;
}
cout<<endl;
}
}
return 0;
}
8.统计每个月兔子的总数
#include <bits/stdc++.h>
using namespace std;
int counts(int m)
{
if (m == 1 || m == 2)
return 1;
return counts(m - 1) + counts(m - 2);
}
int main() {
int m;
while(cin>>m)
{
cout<<counts(m)<<endl;
}
return 0;
}
9.统计字符
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
while (getline(cin, str))
{
int a = 0, b = 0, c = 0, d = 0;
for (int i=0;i<str.length();++i)
{
if (isalpha(str[i]))
++a;
else if (isspace(str[i]))
++b;
else if (isdigit(str[i]))
++c;
else if (ispunct(str[i]))
++d;
}
cout << a << endl << b << endl << c << endl << d << endl;
}
return 0;
}
10. 输出单向链表中倒数第k个结点
#include<iostream>
using namespace std;
struct ListNode{
int m_nKey;
ListNode* m_pNext;
ListNode():m_nKey(0),m_pNext(nullptr){};
ListNode(int x):m_nKey(x),m_pNext(nullptr){};
};
ListNode* getNode(ListNode* node, int& node_num){
if(node==NULL) return NULL;
ListNode* head=getNode(node->m_pNext,node_num);
if(--node_num==0) return node;
else return head;
}
int main(){
int node_num,node;
while(cin>>node_num){
ListNode* head=new ListNode();//正序构建链表
ListNode* pre_head=head;
while(node_num--){
cin>>node;
ListNode* next=new ListNode(node);
head->m_pNext=next;
head=next;
}
cin>>node_num;
ListNode* rec=getNode(pre_head->m_pNext,node_num);//忘记链表长度,递归找到指定节点
if(rec!=NULL) cout<<rec->m_nKey<<endl;
else cout<<"0"<<endl;
}
return 0;
}
11.杨辉三角的变形
//写几行就可以发现规律:
//n==1或2时,没有偶数,cout<<-1;
//n==3时,index=2;
//n==4,index=3;
//n==5,index=2;
//n==6,index=4;
//n==7,index=2;
//n==8,index=3;
//n==9,index=2;
//n==10,index=4;
......
//可以发现,index=2,3,2,4重复出现,将n对4取余,可以发现如下规律:
//n%4==3||n%4==1,index==2;
//n%4==0,index=3;
//n%4==2,index=4;
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
if(n==1||n==2)
{
cout<<-1<<endl;
}
else if(n%4==3||n%4==1)
{
cout<<2<<endl;
}
else if(n%4==0)
{
cout<<3<<endl;
}
else
{
cout<<4<<endl;
}
}
return 0;
}
12.表达式求值
#include<iostream>
#include<stack>
using namespace std;
int pos;
int result(string &data)
{
int num=0;
char flag = '+';
stack<int> st;
int len = data.length();
while(pos<len)
{
if(data[pos] == '(')
{
pos++;
num = result(data);
}
while(pos<len && data[pos]-'0'>=0 && data[pos]-'9'<=0)
{
num =num*10+ data[pos] - '0';
pos ++;
}
switch(flag)
{
case '+':
{
st.push(num);
break;
}
case '-':
{
st.push(-num);
break;
}
case '*':
{
int tmp = st.top();
st.pop();
tmp *= num;
st.push(tmp);
break;
}
case '/':
{
int tmp = st.top();
st.pop();
tmp /= num;
st.push(tmp);
break;
}
}
num = 0;
flag = data[pos];
if(data[pos] == ')')
{
pos ++;
break;
}
pos ++;
}
int sum = 0;
while(st.size())
{
sum += st.top();
st.pop();
}
return sum;
}
int main()
{
string str;
while(cin>>str)
{
pos = 0;
cout<<result(str)<<endl;
}
return 0;
}
13.完全数计算
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n; //待输入的数
while(cin>>n){
int count=0; //计数器
//遍历从2到n的每一个数,并在下一层for计算是否为完全数
for(int k=2;k<=n;k++)
{
int sum=1; //每个数都包含1这个因数
for(int i=2;i<=k/2;i++) //除以2:根据题干推出的缩小i范围的方法
{
if(k%i==0)
sum=sum+i;
}
if(k==sum)
count++;
}
cout<<count<<endl;
}
return 0;
}
14.查找组成一个偶数最接近的两个素数
对于一个数字,我们可以从2遍历到n,寻找两个加数都是素数的情况,然后比较素数之间的差值,把要输出的变量更新为更小的差值及这两个变量,最后枚举完得到就是差值最小的两个素数。
#include<iostream>
using namespace std;
bool isPrime(int n){ //判断数字n是否是素数
for(int i = 2; i < n; i++){ //遍历到n-1
if(n % i == 0) //如果由因子就不是素数
return false;
}
return true; //遍历完都没有就是素数
}
int main(){
int n;
while(cin >> n){
int mindis = n;
pair<int, int> res; //记录两个素数
for(int i = 2; i < n; i++){ //遍历2到n找到两个素数
if(isPrime(i) && isPrime(n - i)){ //两个数都是素数的时候
if(abs(n - i - i) < mindis){ //找距离最小
res = {i, n - i}; //更新最小
mindis = abs(n - i - i);
}
}
}
cout << res.first << endl << res.second << endl;
}
return 0;
}
15.放苹果
'''
放苹果分为两种情况,一种是有盘子为空,一种是每个盘子上都有苹果。
令(m,n)表示将m个苹果放入n个盘子中的摆放方法总数。
1.假设有一个盘子为空,则(m,n)问题转化为将m个苹果放在n-1个盘子上,即求得(m,n-1)即可
2.假设所有盘子都装有苹果,则每个盘子上至少有一个苹果,即最多剩下m-n个苹果,问题转化为将m-n个苹果放到n个盘子上
即求(m-n,n)
'''
def f(m,n):
if m<0 or n<0:
return 0
elif m==1 or n==1:
return 1
else:
return f(m,n-1)+f(m-n,n)
while True:
try:
m,n=map(int,input().split())
print(f(m,n))
except:
break
//
#include <iostream>
using namespace std;
int f(int m,int n){
if(m<0 || n<0)
return 0;
else if(m==1 || n==1)
return 1;
else
return f(m,n-1)+f(m-n,n);
}
int main(){
int m,n;
while(cin >> m >> n){
cout << f(m,n) << endl;
}
return 0;
}
16.百钱买百鸡问题
#include<iostream>
using namespace std;
//鸡翁、鸡母、鸡雏分别为x, y, z 三个变量。
//x+y+z=100
//5x+3y+z/3=100
//确定x即可算出y和z,若y和z为非负整数,则为有效结果,输出。
int main(){
for(int x=0;x<=3;x++){
cout<<4*x<<" "<<25-7*x<<" "<<75+3*x<<endl;
}
return 0;
}