关于string的知识
string;
cin>>s;
遇到开头空格会忽略,遇到最后的空白会结束。
用
while(cin>>s)
{}
可以读取未知数量的字符串
使用getline可以读取一整行(保留空白符)
从给定的输入流中读入内容,直到遇到换行符(line不包含换行符)
使用:
string line;
while(getline(cin,line));
cctype中的一些判断字符串函数:
isalnum©;
isalpha©;
isdigit©;
islower©;
tolower©;
toupper©;
特殊字符判断:
ispunct©;
isprint©;
isspace©;
排序:
sort()
自定义结构vector
#include
#include
#include
using namespace std;
struct Point2
{
int x;
int y;
};
bool GreaterSort (Point2 a,Point2 b) { return (a.x>b.x); }
bool LessSort (Point2 a,Point2 b) { return (a.x<b.x); }
int main()
{
vector<Point2> aaa;
Point2 temp;
temp.x=1;
temp.y=1;
aaa.push_back(temp);
temp.x=2;
temp.y=2;
aaa.push_back(temp);
temp.x=3;
temp.y=3;
aaa.push_back(temp);
sort(aaa.begin(),aaa.end(),GreaterSort);//降序排列
cout<<"Greater Sort:"<<endl;
for (int i =0;i<aaa.size();i++)
{
cout<<aaa[i].x<<" "<<aaa[i].y<<endl;
}
sort(aaa.begin(),aaa.end(),LessSort);//升序排列
cout<<"Less Sort:"<<endl;
for (int i =0;i<aaa.size();i++)
{
cout<<aaa[i].x<<" "<<aaa[i].y<<endl;
}
return 1;
}
sort(v.begin(),v.end());
//使用反向迭代器
#include
using namespace std;
int main()
{
string str("cvicses");
string s(str.rbegin(),str.rend());
cout << s <<endl;
return 0;
}
//输出:sescivc
计算最后一个字符串长度
#include
#include
#include
#include
using namespace std;
int main()
{
string s;
int count=0;
getline(cin,s);
for (int i=s.size()-1; i>=0; i--)
{
if (!isspace(s[i]))
{
++count;
}
else
{
break;
}
}
cout<<count;
}
2
#include
#include
#include
#include
using namespace std;
int main()
{
string s1;
string s2;
int count = 0;
getline(cin, s1);
getline(cin, s2);
for (int i = 0; i < s1.size(); i++)
{
if (s1[i]==s2[0]||s1[i]==toupper(s2[0]))
{
++count;
}
}
cout<<count;
}
#include
using namespace std;
int main() {
int N, n;
while (cin >> N) {
int a[1001] = { 0 };
while (N--) {
cin >> n;
a[n] = 1;
}
for (int i = 0; i < 1001; i++)
if (a[i])
cout << i << endl;
}
return 0;
}
#include
#include
using namespace std;
int main()
{
vector<int>bash(1001);
int n;
vector<int>num;
cin >> n;
while (n--)
{
int nums;
cin >> nums;
num.push_back(nums);
bash[nums]++;
}
for (int i = 0; i <= 1000; i++)
{
if (bash[i]>0)
{
cout << i << endl;
}
bash[i] = 0;
}
}
一直只过了90%
#include
#include
#include
#include
using namespace std;
int main()
{
int cases = 2;
vector<string> result;
while (cases--)
{
string s;
getline(cin, s);
if(s=="")
{
return 0;
}
if (s.size()<8)
{
string tmp;
for (int i = 0; i < 8; i++)
{
if (i>s.size()-1)
{
tmp += '0';
}
else
{
tmp+=s[i];
}
}
result.push_back(tmp);
}
if (s.size() >= 8)
{
string tmp;
int count = 0;
int k = s.size() % 8;
int p = s.size() / 8;
for (int i = 0; i < (p+1)*8; i++)
{
if (i < 8 * p + k)
{
tmp += s[i];
}
if (k!=0&&i>=8*p+k)
{
tmp += '0';
}
count++;
if (count%8==0)
{
result.push_back(tmp);
tmp = "";
}
}
}
}
for (int i = 0; i < result.size(); i++)
{
cout<< result[i] << endl;
}
}
补一个精简的
#include
using namespace std;
int main(){
string str;
while(getline(cin,str)){
while(str.size()>8){
cout << str.substr(0,8) <<endl;//str(pos,len);
//(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s
str=str.substr(8);//好好看好好学
}
cout << str.append(8-str.size(),'0') << endl; //不够8位的补0
}
}
这段代码证明了输入输出不必一次性,可以一个输入一个输出
//example
// string::substr
#include
#include
int main ()
{
std::string str="We think in generalities, but we live in details.";
// (quoting Alfred N. Whitehead)
std::string str2 = str.substr (3,5); // "think"
std::size_t pos = str.find("live"); // position of "live" in str
std::string str3 = str.substr (pos); // get from "live" to the end
std::cout << str2 << ' ' << str3 << '\n';
return 0;
think live in details.
进制转换:
乘方pow(x,y)
字符转数字 int num=s[i]-‘0’;
我的垃圾解法过不了,本地能过,为毛= =
#include
#include
#include
#include
using namespace std;
int main()
{
string str;
while (getline(cin, str))
{
int div = 0;
int count = 0;
for (int i = str.size() - 1; i >=2; i--)
{
if (str[i]=='A')
{
count += 10 * pow(16,div);
div++;
continue;
}
if (str[i] == 'B')
{
count += 11 * pow(16, div);
div++;
continue;
}
if (str[i] == 'C')
{
count += 12 * pow(16, div);
div++;
continue;
}
if (str[i] == 'D')
{
count += 13 * pow(16, div);
continue;
}
if (str[i] == 'E')
{
count += 14 * pow(16, div);
div++;
continue;
}
if (str[i] == 'F')
{
count += 15 * pow(16, div);
div++;
continue;
}
if (str[i] == '0' || str[i] == '1' || str[i] == '2' || str[i] == '3' || str[i] == '4' || str[i] == '5' || str[i] == '6' || str[i] == '7' || str[i] == '8' || str[i] == '9')
{
int num = str[i] - '0';
count += num* pow(16, div);
div++;
}
}
string s = to_string(count);
cout << s;
}
}
正规军:
#include
using namespace std;
int main() {
string str;
while (getline(cin, str)) {
if (str.length() <= 0) break;
long num = 0; int index = 16;
for (int i = 2; i < str.length(); ++i) {
if (str[i] >= '0' && str[i] <= '9')
num = num * 16 + (str[i] - '0');
else
num = num * 16 + (str[i] - 'A' + 10);//好好看好好学
}
cout << num << endl;
}
return 0;
}
奇淫巧计
#include
using namespace std;
int main()
{
int a;
while(cin>>hex>>a){
cout<<a<<endl;
}
}
质数因子:
不会怎么判断质数,直接看
#include
using namespace std;
int main()
{
long num;
cin >> num;
while (num != 1)
{
for (int i = 2; i <= num; i++)
{
if (num%i == 0)
{
num = num / i;
cout << i << ' ';
break;
}
}
}
return 0;
}
用while(cin>>num)不可以,因为是有输入为真,就输入了一次,不会进行第二次循环。
C++ 中 break 语句有以下两种用法:
当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。
它可用于终止 switch 语句中的一个 case。
如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。
#include
#include
using namespace std;
int main()
{
long num;
while(cin>>num)
for(int i=2;i<num;i++)
{
if(num%i==0)
{
num/=i;
cout<<i;
break;//跳出了for但是因为没有后续输入,循环停止
}
}
}
取近似值,向上取整和向下取整怎么搞
ceril() floor()
#include
using namespace std;
int main()
{
float a;
cin>>a;
cout<<int(a+0.5);
return 0;
}
#include
#include
using namespace std;
int main()
{
double num;
while(cin>>num)
{
if(10*(num-int(num))<5)
{
cout<<floor(num);
}
else
{
cout<<ceil(num);
}
}
合并表记录,竟然过了。。
说实话有点像作弊
#include
#include
using namespace std;
int main()
{
vector<int> db(1000,0);
int n;
cin>>n;
while(n--)
{
int ind;int val;
cin>>ind>>val;
db[ind]+=val;
}
for(int i=0;i<=db.size()-1;++i)
{
if(db[i]!=0)
{
cout<<i<<" "<<db[i]<<endl;
}
}
}
提取不重复的整数
#include
#include
#include
using namespace std;
int main()
{
int num;
cin >> num;
string s = to_string(num);
vector<int>bash(10,0);
for (int i = s.size() - 1; i >= 0; --i)
{
int num = s[i] - '0';
if (bash[num]==0)
{
cout << s[i];
}
bash[num] = 1;
}
}
字符个数统计(包含去重,bash真是好用啊)
#include
#include
#include
using namespace std;
int main()
{
string s;
while (cin>>s)
{
int count = 0;
vector<int>bash(128, 0);
for (int i = 0; i < s.size(); i++)
{
int num = (int)s[i];
if (num<127)
{
bash[num]++;
}
}
for (int i = 0; i < 128; i++)
{
if (bash[i]!=0)
{
count++;
}
}
cout << count;
}
}
数字颠倒:to_string真好用
#include
#include
#include
using namespace std;
int main()
{
int num;
cin >> num;
string s;
s = to_string(num);
for (int i = s.size()-1; i >= 0; i--)
{
cout << s[i];
}
}
字符串翻转:这个难度大概是初中生吧
#include
#include
#include
using namespace std;
int main()
{
string s;
while (cin>>s)
{
for (int i = s.size()-1; i >= 0; i--)
{
cout << s[i];
}
}
}
句子逆序
#include
#include
#include
using namespace std;
int main()
{
string s;
vector<string>stack;
while (getline(cin,s))
{
int flag;
int count = 0;
for (int i = 0; i <= s.size()-1; i++)
{
if (i== s.size() - 1)
{
string copy = s.substr(flag + 1, i - flag );
flag = i;
stack.push_back(copy);
}
if (s[i]==' ')
{
count++;
if (count==1)
{
string copy = s.substr(0, i);
flag = i;
stack.push_back(copy);
}
if (count>1)
{
string copy = s.substr(flag+1, i-flag-1);
flag = i;
stack.push_back(copy);
}
}
}
for (int i = stack.size()-1; i >=0; i--)
{
cout << stack[i] << " ";
}
}
}
字符串的字典序排序,其实就是写个排序。。
#include
#include
#include
using namespace std;
int main()
{
int num;
vector<string> dic;
cin >> num;
while (num--)
{
string s;
cin >> s;
dic.push_back(s);
}
for (int i = 0; i <= dic.size()-2; i++)//大的沉底
{
for (int j = 0; j < dic.size()-i-1; j++)
{
if (dic[j+1]<dic[j])
{
string tmp = dic[j];
dic[j] = dic[j + 1];
dic[j + 1] = tmp;
}
}
}
for (int i = 0; i < dic.size(); i++)
{
cout << dic[i] << endl;
}
}
求二进制有多少个1
#include
#include
#include
using namespace std;
int main()
{
int num;
int count = 0;
cin >> num;
while (num!=0)
{
int mod = num % 2;
num = num / 2;
if (mod==1)
{
count++;
}
}
cout << count;
}
数组重置为0
int a[SIZE];
memset(a, 0, sizeof(a));
memset(a, 0, sizeof(int)*1000);//这里的1000是数组大小,需要多少替换下就可以了。
vector重置为0
std::fill(v.begin(), v.end(), 0); 用过都说好
购物清单问题
这个类型没做过,写了一个多小时没写出来。
涉及到了经典的0-1背包问题,看看看
动态规划的⼀般流程就是三步:
暴⼒的递归解法 -> 带备忘录的 递归解法 -> 迭代的动态规划解法
思考流程来说,就分为⼀下⼏步:
找到状态和选择 -> 明确 dp 数组/函数 的定义 -> 寻找状态之间的关系
重叠⼦问题、最优⼦结构、状态转移⽅程就是动态规划三要素
流程:
先确定状态:在这个问题和子问题变化的时候变量是什么
确定dp函数的定义:一般是我们的目标
确定选择并择优:一般是 状态=min(状态,子问题的情况)
明确base case: 一般是0和1的情况。
这个过程既可以自顶向下递归(备忘录)也可以自底向上迭代。、
计算机解决问题其实没有任何奇技淫巧,它唯⼀的解决办法就是穷举
碰到那种恶⼼⼈的最值题,思路往动态规划想。
经典问题:
凑硬币
最长递增子序列
01背包问题
例子:
招行fintech
掉金币
#include
#include
#include
#include
using namespace std;
int a[1030][1030], n, mem[1030][1030];
int f(int i, int j) {
if (i == n) return a[i][j];
if (mem[i][j] != -1) return mem[i][j];//这句是mem的精髓
return mem[i][j] = max(f(i+1, j), f(i+1, j+1)) + a[i][j];
}
int main() {
memset(mem, -1, sizeof(mem));
cin >> n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= i; ++j)
cin >> a[i][j];
}
cout << f(1, 1);
return 0;
}