木块问题
#include<cstdio>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
int n;
const int maxn=30;
vector<int>pile[maxn];
void find_block(int a,int& p,int& h){//获取a的位置和高度
for(p=0;p<n;p++){
for(h=0;h<pile[p].size();h++){
if(pile[p][h]==a)return;//立刻结束
}
}
}
void clear_above(int p,int h){//将h以上的块归位
for(int i=h+1;i<pile[p].size();i++){
int b=pile[p][i];
pile[b].push_back(b);
//最后添加的元素会被认为是最上面的元素,所以通过将块b添加到堆栈b的末尾,就相当于将它归位到原先的位置。
}
pile[p].resize(h+1);//更新pile大小为0到h
}
void pile_onto(int p,int h,int p2){//h及上方所有块移到p2堆顶部
for(int i=h;i<pile[p].size();i++){
pile[p2].push_back(pile[p][i]);
}
pile[p].resize(h);
}
int main(){
int a,b;
cin>>n;
string s1,s2;
for(int i=0;i<n;i++){
pile[i].push_back(i);//栈初始化
}
while(cin>>s1>>a>>s2>>b){
int pa,pb,ha,hb;
find_block(a,pa,ha);
find_block(b,pb,hb);
if(pa==pb)continue;
if(s2=="onto")clear_above(pb,hb);
if(s1=="move")clear_above(pa,ha);
pile_onto(pa,ha,pb);
}
print();
}
stl汇总
字符串转数字+重载运算符
sort(a,a+n);//a到a+n排序
int p=lower_bound(a,a+n,x)-a;//获取第一个比a大或等于a的元素下标
string line;//将字符串流直接转整数
while(getline(cin,line)){
int sum=0,x;
stringstream ss(line);
while(ss>>x)sum+=x;
cout<<sum<<"\n";
}
struct point{
int x,y;
point(int x=0,int y=0):x(x),y(y){}//x(x)相当于 this->x = x;
};
point operator+(const point& a,const point& b){
return point(a.x+b.x,a.y+b.y);
}
ostream& operator<<(ostream &out,const point& p){
//重载了输出流 << 运算符,使得能够直接使用 cout 输出 point 类型的对象
out<<"("<<p.x<<","<<p.y<<")";
return out;
}
int main(void){
point a,b(1,2);
a.x=3;
cout<<a+b<<"\n";
}
实现各种类型相加
template<typename T>
T sum(T* a,T* b){
T *p=a;
T ans=0;
for(T* p=a;p!=b;p++){
ans=ans+*p;//不能用+=
return ans;
}
}
字符串按字典序排
set<string>dict;//里头的元素自动从小到大排列
int main(void){
string s,buf;
while(cin>>s){
for(int i=0;i<s.length();i++){
if(isalpha(s[i]))s[i]=tolower(s[i]);//isalpha判断是否为字母,tolower转小写
else s[i]=' ';
}
stringstream ss(s);
while(ss>>buf)dict.insert(buf);//dict中插入buf
}
for(set<string>::iterator it=dict.begin();it!=dict.end;++it){//set<string>::iterator为string的迭代器
cout<<*it<<"\n";//it指向集合中某个元素的位置,*it为值
}
}
字符串从大写到小写按字典序排(有映射版)
map<string,int>cnt;
string repr(const string& s){
//可以将任意类型的对象转换为字符串表示,这样就可以保证排序函数能够正确比较和排序字典中的键或值
string ans=s;
for(int i=0;i<s.length();i++){
ans[i]=tolower(ans[i]);
}
sort(ans.begin(),ans.end());//
return ans;
}
vector<string>words;
int main(void){
string s;
int n=0;
while(cin>>s){
if(s[0]=='#')break;
words.push_back(s);
string r=repr(s);
if(!cnt.count(r))cnt[r]=0;//计数前初始化
cnt[r]++;//记录r出现次数
//还是不明白为什么cnt.count(r)不能代替cnt[r]
}
vector<string>ans;
for(int i=0;i<words.size();i++){
if(cnt[repr(words[i])]==1)ans.push_back(words[i]);
}
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++){
cout<<ans[i]<<"\n";
}
}
当repr中定义vector<char>ans; 时
string repr(string b){
vector<char>ans;
for(int i=0;i<b.length();i++){
ans.push_back(tolower(b[i]));//
}
sort(ans.begin(),ans.end());
return string(ans.begin(),ans.end());//
}
思路:创建装所有单词的string组words,记录字符串出现次数的映射cnt,记录输出字符串的string组ans。repr中创建字符串ans,直接将字符串小写且按从小到大字母排(方便判断重排是否重复)