CSP普及赛基础算法练习1
洛谷 P1010 幂次方 -分治算法
https://www.luogu.com.cn/problem/P1010
#include<bits/stdc++.h> using namespace std; void compute(int x){ if (x==0) return; //递归结束条件 //可以求出2的对数 舍去小数 比如:log2(8)=3 log2(7) int t = log2(x); if (t==0){ cout<<"2(0)"; //2的0次方 } if (t==1){ cout<<"2"; //2的1次方 } if (t>1) {//大于2的1次方,递归 cout<<"2("; compute(t); cout<<")";//结束递归后添加 } if (pow(2,t)!=x) {//x不等于pow(2,t),说明后面还接着数 cout<<"+"; compute(int(x-pow(2,t))); } } int main(){ int n; cin >> n; compute(n); return 0; }
洛谷 P1908 逆序对 -分治算法
https://www.luogu.com.cn/problem/P1908
#include<iostream> using namespace std; int tmp[500001],nums[500001]; long long sum; void margeSort(int arr[],int l,int r) { if (l>=r)return; int mid =l+((r-l)>>1);//找中间点 margeSort(arr,l,mid); margeSort(arr,mid+1,r); int li=l,ri=mid+1,ti=0; //每次右边(mid+1~r)放入时说明该数比arr[li]小, // 所以没放入的左边(li~mid)都比该数大,就添加(mid+1)-li个逆序对即可. while (li<=mid && ri<=r) { if (arr[li]<=arr[ri]){ tmp[ti++]=arr[li++]; }else{ tmp[ti++]=arr[ri++]; sum+=(long long)mid+1-li; } } while (li<=mid){ tmp[ti++]=arr[li++]; } while (ri<=r){ tmp[ti++]=arr[ri++]; } for(int i=l;i<=r;i++)arr[i]=tmp[i-l]; } int main() { int n; cin >> n; for (int i=0;i<n;i++){ cin>>nums[i]; } margeSort(nums,0,n-1); cout<<sum; return 0; }
洛谷 P2240 部分背包问题 - 贪心算法
https://www.luogu.com.cn/problem/P2240
#include<bits/stdc++.h> using namespace std; struct treasure{ int weight; double price; double value; }; bool cmp(treasure ts1,treasure ts2){ return ts1.price>ts2.price; } int main(){ int n,t; cin>>n>>t; treasure ts[n]; for(int i=0;i<n;i++){ cin>>ts[i].weight>>ts[i].value; ts[i].price=ts[i].value/ts[i].weight; } sort(ts,ts+n,cmp); double ans=0; for(int i=0;i<n;i++){ if(ts[i].weight<=t){ ans+=ts[i].value; t-=ts[i].weight; }else{ ans+=ts[i].price*t; break; } } cout<<fixed<<setprecision(2)<<ans; }
洛谷 P1151 子数整数 - 枚举
https://www.luogu.com.cn/problem/P1151
#include<bits/stdc++.h> using namespace std; int main(){ int k; cin>>k; bool flag = false; for(int i=10000;i<=30000;i++){ //拆a1a2a3 int temp1 = i/100; //取a2a3a4 // i/10000*10000 保留整万 //i-i/10000*10000 去除首位比如:23456变成3456 //(i-i/10000*10000)/10 --23456变成3456变成345 int temp2 =(i-i/10000*10000)/10; //取a3a4a5 int temp3 = i%1000; //判断对应子项是否被k整除 if(temp1%k==0 && temp2%k==0 && temp3%k==0){ cout<<i<<endl; flag = true; } } if(!flag){ cout<<"No"; } }
洛谷 P1211 牛式 Prime Cryptarithm - 枚举
https://www.luogu.com.cn/problem/P1211
#include<bits/stdc++.h> using namespace std; bool a[10]; //是否给定数字 bool isValid(int n){ while(n){ if(a[n%10]==0){ return false; } n/=10; } return true; } int main(){ int n; cin>>n; int temp; for(int i=0;i<n;i++){ cin>>temp; a[temp]=1; } int ans=0; for(int i=100;i<=999;i++){ for(int j=10;j<=99;j++){//枚举两个乘数 int ge= j%10; int shi = j/10; if(i*ge>999){//第一个数*第二个数个位 continue; } if(i*shi>999){//第一个数*第二个数十位 continue; } if(i*j>9999){//第一个数*第二个数十位 continue; } //i j i*j的个位 i*j的十位 i*j必须都是给定的数字 if(isValid(i)&&isValid(j)&&isValid(i*ge)&&isValid(i*shi)&&isValid(i*j)){ ans++; } } } cout<<ans<<endl; return 0; }
洛谷 P1059 明明的随机数 - 排序
https://www.luogu.com.cn/problem/P1059
#include<bits/stdc++.h> using namespace std; int n,a[107],t; int main(){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); int cnt=1; //去重 重复的把前面一个清0 for(int i=1;i<n;i++){ if(a[i]==a[i-1]){ a[i-1]=0; }else{ cnt++; } } printf("%d\n",cnt); for(int i=0;i<n;i++){ if(a[i]>0){ printf("%d ",a[i]); } } return 0; }
洛谷 P1068 分数线划定 - 排序
https://www.luogu.com.cn/problem/P1068
#include<bits/stdc++.h> using namespace std; struct student{ int no; int score; }; //排序规则 //分数从大到小 分数相同按学号从小到大 bool cmp(student st1,student st2){ if(st1.score!=st2.score) return st1.score>st2.score; return st1.no<st2.no; } student students[5005]; int n,m; int main(){ cin>>n>>m; for(int i=0;i<n;i++){ cin>>students[i].no; cin>>students[i].score; } sort(students,students+n,cmp); m=m*1.5;//面试人数 向下取整 //分数线 最后一个录取的人分数 int mscore = students[m-1].score; int retCnt = m;//记录录取人数 //计算实际录取人数-最后一个分数多个,相同都录取 for(int i=m;i<n;i++){ if(students[i].score==mscore){ retCnt++; }else{ break; } } cout<<mscore<<" "<<retCnt<<endl; for(int i=0;i<retCnt;i++){ cout<<students[i].no<<" "<<students[i].score<<endl; } }
洛谷 P1093 [NOIP2007 普及组] 奖学金 - 排序
https://www.luogu.com.cn/problem/P1093
#include<bits/stdc++.h> using namespace std; struct stx{ int yw,sx,yy;//yw 语文成绩,sx数学成绩, yy英语成绩 int sum,no;//总分,学号 }score[501]; //排序规则 //按总分从大到小 //总分相同按语文从大到小 //总分和语文相同 按学号从小到大 int cmp(stx x1,stx x2){ if(x1.sum!=x2.sum) return x1.sum>x2.sum; if(x1.yw!=x2.yw) return x1.yw>x2.yw; return x1.no<x2.no; } int main(){ int n; cin>>n; //读取数据到数据结构体 for(int i=1;i<=n;i++){ cin>>score[i].yw>>score[i].sx>>score[i].yy; score[i].sum=score[i].yw+score[i].sx+score[i].yy; score[i].no=i; } //sort从第一个开始的n个人排序 sort(score+1,score+n+1,cmp); //取前5人 for(int i=1;i<=5;i++){ cout<<score[i].no<<" "<<score[i].sum<<endl; } }
作者:newcode 更多资源请关注纽扣编程微信公众号

从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习

浙公网安备 33010602011771号