先把基础搞好,所以把这本书刷一遍!!!
ALDS1_1_D:Maximum Profit
#include
using namespace std;
int n,ma=INT_MIN,mi=INT_MAX,num;//以前没注意,
//可以直接设置int的最大值和最小值为INT_MAX和INT_MIN
int main()
{
cin>>n;
for(int i=0;i<n;i++){
cin>>num;
ma=max(ma,num-mi);//更新差值最大值
mi=min(mi,num);//一直更新i之前的最小值
}
cout<<ma<<"\n";
}
ALDS1_1_A:Insertion Sort
#include
using namespace std;
const int maxn=100+10;
int n,arr[maxn];
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++){
int v=arr[i];//需要排序的数
int j=i-1;
while(j>=0&&arr[j]>v){//将比v大的数字都向后平移一位
arr[j+1]=arr[j];
j--;
}
arr[j+1]=v;//将v插入到比v都大的数字向后平移一位以后留出来的那个空隙里
for(int i=0;i<n;i++){
if(i) cout<<" "<<arr[i];
else cout<<arr[i];
}cout<<"\n";
}
}
ALDS1_2_A:Bubble Sort
#include
using namespace std;
const int maxn=100+10;
int n,arr[maxn],cnt=0;
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
bool flag=1;
for(int i=0;flag;i++){
flag=0;//如果在一轮循环中没有交换,说明已经排序完毕,就终止循环
for(int j=n-1;j>i;j--){//从后往前排
if(arr[j-1]>arr[j]){
flag=1;
swap(arr[j],arr[j-1]);
cnt++;
}
}
}
for(int i=0;i<n;i++){
if(i) cout<<" ";
cout<<arr[i];
}
cout<<"\n"<<cnt<<"\n";
}
ALDS1_2_B:Selection Sort
//方法1
#include
using namespace std;
const int maxn=100+10;
int n,arr[maxn],cnt=0;
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++){
int minj=i;
for(int j=i;j<n;j++){//记录未排序序列中的最小值的下标
if(arr[j]<arr[minj]){
minj=j;
}
}
if(i!=minj){
cnt++;
swap(arr[i],arr[minj]);
}
}
for(int i=0;i<n;i++){
if(i) cout<<" ";
cout<<arr[i];
}
cout<<"\n"<<cnt<<"\n";
}
//方法2
#include
using namespace std;
const int maxn=100+10;
int n,arr[maxn],cnt=0;
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++){
int minj=i;
minj=min_element(arr+i,arr+n)-arr;//min_element返回的是数组最小值位置指针,获取最小值用*min_element(begin,end),获取最小值下标用min_element(begin,end)-arr
if(i!=minj){
cnt++;
swap(arr[i],arr[minj]);
}
}
for(int i=0;i<n;i++){
if(i) cout<<" ";
cout<<arr[i];
}
cout<<"\n"<<cnt<<"\n";
}
ALDS1_3_A:Stack
#include
using namespace std;
int main()
{
stack<int>st;
char s[100];
while(cin>>s){
int a,b;
if(s[0]=='+'){
a=st.top();st.pop();
b=st.top();st.pop();
st.push(b+a);
}else if(s[0]=='-'){
a=st.top();st.pop();
b=st.top();st.pop();
st.push(b-a);
}else if(s[0]=='*'){
a=st.top();st.pop();
b=st.top();st.pop();
st.push(b*a);
}else st.push(atoi(s));//atoi()用来将字符串形式的数字转换为整形数值
}
cout<<st.top()<<"\n";
}
ALDS1_3_B:Queue
#include
using namespace std;
struct node {
char name[100];
int t;
};
int main() {
int n,q,t;
scanf("%d%d",&n,&q);
queue<node>qu;//可以用queue >qu代替
for(int i=0; i<n; i++) {
node N;
scanf("%s%d",N.name,&N.t);
qu.push(N);
}
int sum=0;
while(!qu.empty()) {
node this_node=qu.front();
qu.pop();
sum+=min(this_node.t,q);
if(this_node.t<=q) {
printf("%s %d\n",this_node.name,sum);
} else {
this_node.t-=q;
qu.push(this_node);
}
}
}
ALDS1_3_C:Doubly Linked List
#include
using namespace std;
int main()
{
list<int>lst;
int num;char c[20];
int n;scanf("%d",&n);
while(n--){
scanf("%s",c);
if(c[0]=='i') {scanf("%d",&num);lst.push_front(num);}
else if(c[6]=='F') lst.pop_front();//deleteFirst
else if(c[6]=='L') lst.pop_back();//deleteLast
else if(c[0]=='d'){
scanf("%d",&num);
for(list<int>::iterator it=lst.begin();it!=lst.end();it++){
if(*it==num) {
lst.erase(it);break;
}
}
}
}
int i=0;
for(list<int>::iterator it=lst.begin();it!=lst.end();it++) {
if(i++) printf(" ");
printf("%d",*it);
}
printf("\n");
return 0;
}
//不用STL的
#include
using namespace std;
struct Node {
int key;
Node *prev,*next;
};
Node *nil;
void init() {
nil=(Node *)malloc(sizeof(Node));
nil->next=nil;
nil->prev=nil;
}
Node * listSearch(int key) {
Node *cur=nil->next;//从头节点后面的元素开始访问
while(cur!=nil&&cur->key!=key) {
cur=cur->next;
}
return cur;
}
void printList() {
Node *cur=nil->next;
int isf=0;
while(1) {
if(cur==nil) break;
if(isf++>0) printf(" ");
printf("%d",cur->key);
cur=cur->next;
}
printf("\n");
}
void deleteNode(Node *t) {
if(t==nil) return ;//t为头结点时不做处理
t->prev->next=t->next;
t->next->prev=t->prev;
free(t);
}
void deleteFirst() {
deleteNode(nil->next);
}
void deleteLast() {
deleteNode(nil->prev);
}
void deleteKey(int key){
deleteNode(listSearch(key));
}
void insert(int key){
Node *x=(Node *)malloc(sizeof(Node));
x->key=key;
//在头节点后添加元素
x->next=nil->next;
x->next->prev=x;
nil->next=x;
x->prev=nil;
}
int main() {
char c[20];
int n,num;
init();
scanf("%d",&n);
while(n--){
scanf("%s",c);
if(c[0]=='i') {scanf("%d",&num);insert(num);}
else if(c[6]=='F') deleteFirst();
else if(c[6]=='L') deleteLast();
else if(c[0]=='d'){
scanf("%d",&num);
deleteKey(num);
}
}
printList();
}
ALDS1_3_D:Areas on the Cross-Section Diagram
这题就是求所有积水区域的总面积和有多少各个积水区域的面积分别是多少。
#include
using namespace std;
int main()
{
stack<int>st;//用来存储\的位置j,用来求单对\/形成的面积(相当于一层一层的算)
//单对\/形成的面积是i-j
stack<pair<int,int> >area;
char c;
int sum=0;
for(int i=0;cin>>c;i++){
if(c=='\\') st.push(i);
else if(c=='/'&&st.size()>0){
int j=st.top();st.pop();
sum+=(i-j);//单对\/形成的面积是i-j
int a=i-j;
while(area.size()>0&&area.top().first>j){//如果当前匹配到的一对\/的左边的\的位置比已经存到area中的那个区域面积最左边的\的位置小,
//说明需要合并
a+=area.top().second;area.pop();
}
area.push(make_pair(j,a));//合并好的push进去
}
}
vector<int>ans;
while(!area.empty()){
ans.push_back(area.top().second);
area.pop();
}
reverse(ans.begin(),ans.end());
cout<<sum<<"\n"<<ans.size();
for(auto i:ans){
cout<<" "<<i;
}
cout<<"\n";
}
ALDS1_4_A:Linear Search
#include
using namespace std;
const int maxn=1e4+10;
int main()
{
int n,q,S[maxn],key;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&S[i]);
sort(S,S+n);
scanf("%d",&q);
int cnt=0;
for(int i=0;i<q;i++) {
scanf("%d",&key);
if(*lower_bound(S,S+n,key)==key) cnt++;
}
printf("%d\n",cnt);
}
ALDS1_4_B Binary Search
#include
using namespace std;
vector<int>S;
int bisearch(int n,int a){
int left=0,right=n;
while(left<right){
int mid=left+(right-left)/2;
if(a==S[mid]) return 1;
else if(a<S[mid]) right=mid;
else left=mid+1;
}
return 0;
}
int main()
{
int n,a,q,cnt=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a);
S.push_back(a);
}
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d",&a);
cnt+=bisearch(n,a);
}
printf("%d\n",cnt);
}
ALDS1_4_C:Dictionary
ALDS1_5_A:Exhaustive Search
#include
using namespace std;
const int maxn=20+5;
int n,num,arr[maxn],q,vis[400010];
void dfs(int cur,int sum){//再vis数组中标记arr数组中的数所有组合方式产生的数字和
if(cur==n) return ;
vis[sum]=1;
dfs(cur+1,sum+arr[cur+1]);
dfs(cur+1,sum);
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
cin>>q;
dfs(-1,0);
while(q--){
cin>>num;
if(vis[num]) cout<<"yes\n";
else cout<<"no\n";
}
}
#include
using namespace std;
const int maxn=20+5;
int n,arr[maxn],q,num;
bool solve(int idx,int m){//表示再arr数组下标从idx往后能不能组成m
if(m==0) return true;
if(idx==n) return false;//这两个if顺序不能反,注意边界
return solve(idx+1,m)||solve(idx+1,m-arr[idx]);
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
cin>>q;
while(q--){
cin>>num;
if(solve(0,num)) cout<<"yes\n";
else cout<<"no\n";
}
}
ALDS1_5_B:Merge Sort
#include
using namespace std;
#define LL long long
#define INF INT_MAX
const int maxn=5e5+10;
int L[maxn/2+2],R[maxn/2+2];
int cnt;
void merge(int A[],int n,int left,int mid,int right){
int n1=mid-left;
int n2=right-mid;
for(int i=0;i<n1;i++) L[i]=A[left+i];
for(int i=0;i<n2;i++) R[i]=A[mid+i];
L[n1]=R[n2]=INF;
int i=0,j=0;
for(int k=left;k<right;k++){
cnt++;//记录比较次数
if(L[i]<=R[j]) A[k]=L[i++];
else A[k]=R[j++];
}
}
void mergeSort(int A[],int n,int left,int right){
if(left+1<right){
int mid=(left+right)/2;
mergeSort(A,n,left,mid);
mergeSort(A,n,mid,right);
merge(A,n,left,mid,right);
}
}
int main()
{
int A[maxn],n;
cnt=0;
cin>>n;
for(int i=0;i<n;i++){
cin>>A[i];
}
mergeSort(A,n,0,n);
for(int i=0;i<n;i++){
if(i) cout<<" ";
cout<<A[i];
}cout<<endl;
cout<<cnt<<endl;
}
ALDS1_7_A:Rooted Trees
用的是左子右兄弟表示法(left-child right-sibling representation)表示树
#include
using namespace std;
#define NIL -1
const int MAX=1e5+10;
struct Node{
int p,l,r;//parent,left,right
Node(int p=NIL,int l=NIL,int r=NIL){
this->p=p;this->l=l;this->r=r;
}
}T[MAX];
int n,D[MAX];//D是深度,O(n)递归求
void rec(int cur,int dep){
D[cur]=dep;
if(T[cur].l!=NIL) rec(T[cur].l,dep+1);
if(T[cur].r!=NIL) rec(T[cur].r,dep);
}
void print(int cur){
cout<<"node "<<cur<<": parent = "<<T[cur].p<<", "<<"depth = "<<D[cur]<<", ";
if(T[cur].p==NIL) cout<<"root, [";
else if(T[cur].l==NIL) cout<<"leaf, [";
else cout<<"internal node, [";
for(int i=0,c=T[cur].l;c!=NIL;c=T[c].r,i++){
if(i) cout<<", ";
cout<<c;
}
cout<<"]\n";
}
int main()
{
int id,k,v;
cin>>n;
for(int i=0;i<n;i++){
cin>>id>>k;
int rr;
for(int j=0;j<k;j++){
cin>>v;
if(j==0) T[id].l=v;
else T[rr].r=v;
rr=v;
T[v].p=id;
}
}
int root;
for(int i=0;i<n;i++) if(T[i].p==NIL) {root=i;break;}//找根节点
rec(root,0);
for(int i=0;i<n;i++) print(i);
}
ALDS1_7_B:Binary Trees
#include
#define NIL -1
using namespace std;
const int MAX=30;
int n,D[MAX],H[MAX];
struct Node{
int p,l,r;//parent,left,right
Node(int p=NIL){this->p=p;}
}T[MAX];
void setDepth(int cur,int dep){
D[cur]=dep;
if(T[cur].l!=NIL) setDepth(T[cur].l,dep+1);
if(T[cur].r!=NIL) setDepth(T[cur].r,dep+1);
}
int setHeight(int cur){
int hl=0,hr=0;
if(T[cur].l!=NIL) hl=setHeight(T[cur].l)+1;
if(T[cur].r!=NIL) hr=setHeight(T[cur].r)+1;
return H[cur]=max(hl,hr);
}
int getSibling(int cur){
if(T[cur].p==NIL) return NIL;
if(T[T[cur].p].l!=cur&&T[T[cur].p].l!=NIL) return T[T[cur].p].l;
if(T[T[cur].p].r!=cur&&T[T[cur].p].r!=NIL) return T[T[cur].p].r;
return NIL;
}
int getDegree(int cur){
int deg=0;
if(T[cur].l!=NIL) deg++;
if(T[cur].r!=NIL) deg++;
return deg;
}
void print(int cur){
cout<<"node "<<cur<<": parent = "<<T[cur].p<<", sibling = "<<getSibling(cur)<<", degree = ";
cout<<getDegree(cur)<<", depth = "<<D[cur]<<", height = "<<H[cur]<<", ";
if(T[cur].p==NIL) cout<<"root\n";
else if(T[cur].l==NIL&&T[cur].r==NIL) cout<<"leaf\n";
else cout<<"internal node\n";
}
int main()
{
int id,left,right;
cin>>n;
for(int i=0;i<n;i++){
cin>>id>>left>>right;
T[id].l=left;
T[id].r=right;
if(left!=NIL) T[left].p=id;//判断一下,防止数组越界
if(right!=NIL) T[right].p=id;
}
int root;
for(int i=0;i<n;i++) if(T[i].p==NIL){root=i;break;}
setDepth(root,0);
setHeight(root);
for(int i=0;i<n;i++) print(i);
}
ALDS1_7_C:Tree Walk
#include
#define NIL -1
using namespace std;
const int maxn=30;
struct Node{
int p,l,r;
Node(int p=NIL){this->p=p;}
}T[maxn];
void Preorder(int cur){
if(cur==NIL) return ;
cout<<" "<<cur;
Preorder(T[cur].l);
Preorder(T[cur].r);
}
void Inorder(int cur){
if(cur==NIL) return ;
Inorder(T[cur].l);
cout<<" "<<cur;
Inorder(T[cur].r);
}
void Postorder(int cur){
if(cur==NIL) return ;
Postorder(T[cur].l);
Postorder(T[cur].r);
cout<<" "<<cur;
}
int main()
{
int n,id,ll,rr;
cin>>n;
for(int i=0;i<n;i++){
cin>>id>>ll>>rr;
T[id].l=ll;
T[id].r=rr;
if(ll!=NIL) T[ll].p=id;
if(rr!=NIL) T[rr].p=id;
}
int root;
for(int i=0;i<n;i++) if(T[i].p==NIL) {root=i;break;}
cout<<"Preorder\n";
Preorder(root);
cout<<"\nInorder\n";
Inorder(root);
cout<<"\nPostorder\n";
Postorder(root);
cout<<"\n";
}
ALDS1_10_A:Fibonacci Number
ALDS1_11_C:Breadth First Search
#include
using namespace std;
const int maxn=100+10;
int n,G[maxn][maxn],dis[maxn],vis[maxn];
void bfs(){
memset(dis,0,sizeof dis);
memset(vis,0,sizeof vis);
queue<int>que;
que.push(1);vis[1]=1;dis[1]=0;
while(!que.empty()){
int cur=que.front();que.pop();
for(int i=1;i<=n;i++){
if(G[cur][i]&&!vis[i]){
que.push(i);
dis[i]=dis[cur]+1;
vis[i]=1;
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
int u,k;cin>>u>>k;
for(int j=0;j<k;j++){
int v;cin>>v;
G[u][v]=1;
}
}
bfs();
for(int i=1;i<=n;i++) if(!vis[i]) dis[i]=-1;//在bfs完以后还没到达的点到1点的距离设置为-1
for(int i=1;i<=n;i++) cout<<i<<" "<<dis[i]<<"\n";
}
//用邻接表写
#include
using namespace std;
const int maxn=100+10;
int n,dis[maxn],vis[maxn];
vector<int>G[maxn];
void bfs(){
memset(dis,0,sizeof dis);
memset(vis,0,sizeof vis);
queue<int>que;
que.push(1);vis[1]=1;dis[1]=0;
while(!que.empty()){
int cur=que.front();que.pop();
for(auto i:G[cur]){
if(!vis[i]){
que.push(i);
dis[i]=dis[cur]+1;
vis[i]=1;
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
int u,k;cin>>u>>k;
for(int j=0;j<k;j++){
int v;cin>>v;
G[u].push_back(v);
}
}
bfs();
for(int i=1;i<=n;i++) if(!vis[i]) dis[i]=-1;//在bfs完以后还没到达的点到1点的距离设置为-1
for(int i=1;i<=n;i++) cout<<i<<" "<<dis[i]<<"\n";
}
DPL_1_D:Longest Increasing Subsequence
lower_bound(arr,arr+n,x)是在arr数组(已排序)中二分查找第一个大于等于x的数的位置指针
#include
using namespace std;
const int maxn=1e5+10;
int arr[maxn],n,L[maxn];
const int inf=0x3f3f3f3f;
int main()
{
memset(L,inf,sizeof L);
cin>>n;
for(int i=0;i<n;i++){
cin>>arr[i];
*lower_bound(L,L+n,arr[i])=arr[i];
}
cout<<lower_bound(L,L+n,inf)-L<<"\n";
}