🍰🍰🍰hello宝子们,今天我们来练习浙江大学的机试题目。加油!fighting!( •̀ ω •́ )✧
1🍩1320 统计字符
直接暴力解!
#include<bits/stdc++.h>
using namespace std;
int main(){
string s,s2;
while(getline(cin,s)){
if(s=="#") break;
getline(cin,s2);
for(int i=0;i<s.size();i++){
int ans=0;
for(int j=0;j<s2.size();j++){
if(s2[j]==s[i]) ans++;
}
cout<<s[i]<<" "<<ans<<endl;
}
}
return 0;
}
2🍩1312 通畅工程
用kruskal(最小生成树)+并查集(判断连通问题)!
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
struct node {
int u, v, w;
}edge[maxn*maxn];
int cmp(node A, node B) {return A.w < B.w;}
int fa[maxn];//记录并查集的数组
int find(int x){//用并查集检查连通问题
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
int main(){
int N,M;
while(cin>>M>>N){//M个村庄、N条边,不太符合我们平时的习惯,我们换过来,N个村庄、M条边
if(M==0) break;
for(int i=0;i<M;i++) cin>>edge[i].u>>edge[i].v>>edge[i].w;
for(int i=1;i<=N;i++) fa[i]=i;
sort(edge,edge+M,cmp);//kruskal算法的核心思想,按边选
int ans=0;
int total=0;
for(int i=0;i<M;i++){//处理所有的边
int x=find(edge[i].u);
int y=find(edge[i].v);
if(x!=y){//merge部分
fa[x]=y;
ans+=edge[i].w;
total++;//统计加入边数量
}
}
if(total<N-1)//不能生成树
cout<<"?"<<endl;
else cout<<ans<<endl;
}
return 0;
}
3🍩1329 统计同成绩学生人数
直接暴力!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,a[1005],cur;
while(cin>>n)
{
if(n==0) break;
for(int i=0;i<n;i++) cin>>a[i];
cin>>cur;
int ans=0;
for(int i=0;i<n;i++){
if(a[i]==cur) ans++;
}
cout<<ans<<endl;
}
return 0;
}
4🍩1319 通畅工程2
用并查集!n个点共最少需要n-1条边连通!
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
struct node{
int u,v;
}edge[N*N];
int fa[N];
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
int main(){
int n,m;
while(cin>>n){
if(n==0) break;
cin>>m;
for(int i=0;i<m;i++) cin>>edge[i].u>>edge[i].v;
for(int i=1;i<=n;i++) fa[i]=i;
int total=0;
for(int i=0;i<m;i++){
int x=find(edge[i].u),y=find(edge[i].v);
if(x!=y){
fa[x]=y;
total++;
}
}
if(total>=n-1) cout<<0<<endl;
else cout<<(n-1)-total<<endl;
}
return 0;
}
5🍩1317 二叉搜索树
二叉搜索树构建对比模板题!
#include<bits/stdc++.h>
using namespace std;
struct tree{
int data;
struct tree *lchild,*rchild;
};
void Insert(struct tree* &root,int cur){
if(root==NULL){
root=new tree;
root->data=cur;
root->lchild=NULL;
root->rchild=NULL;
return;
}
else if(cur<root->data) Insert(root->lchild,cur);
else if(cur>root->data) Insert(root->rchild,cur);
else if(cur==root->data) return;
}
bool cmp(struct tree *r1,struct tree *r2){
if(r1==NULL&&r2==NULL) return true;
if(r1==NULL||r2==NULL) return false;
if(r1->data!=r2->data) return false;
return cmp(r1->lchild,r2->lchild)&&cmp(r1->rchild,r2->rchild);
}
int main(){
int n;
cin>>n;
string s,s2;
cin>>s;
struct tree* t1=NULL;
int len1=s.size();
for(int i=0;i<len1;i++) Insert(t1,s[i]-'0');
while(n--){
struct tree* t2=NULL;
cin>>s2;
int len2=s2.size();
for(int i=0;i<len2;i++) Insert(t2,s2[i]-'0');
if(cmp(t1,t2)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
6🍩1334 最大连续子序列
采用动态规划,dp[i]用来记录,到i这个位置最大连续子序列的和的大小!
#include<bits/stdc++.h>
using namespace std;
int dp[10005];//dp中存放到当前位置的最大连续子序列的大小
int main(){
int n,a[10005]={0};
while(cin>>n){
if(n==0) break;
int fushu=0;
for(long long i=0;i<n;i++){
cin>>a[i];
if(a[i]<0) fushu++;
}
int maxm=0,temp=0,s,d;
if(n==1){//只有一个元素的情况
cout<<a[0]<<" "<<a[0]<<" "<<a[0]<<endl;
}else if(fushu==n){//全负的情况
cout<<"0 "<<a[0]<<" "<<a[n-1]<<endl;
}else{
dp[0]=a[0];
maxm=dp[0];
s=1;//最大连续子序列开始的下标
d=1;//最大连续子序列结束的下标
for(long long i=1;i<n;i++){
if(dp[i-1]+a[i]<a[i]){//取最大的情况
dp[i]=a[i];
temp=i;
}
else{
dp[i]=dp[i-1]+a[i];
}
if(dp[i]>maxm){
maxm=dp[i];
s=temp;
d=i;
}
}
cout<<maxm<<" "<<a[s]<<" "<<a[d]<<endl;
}
}
return 0;
}
7🍩1338 EXCEL排序
这道题目就是简单模拟!
#include<bits/stdc++.h>
using namespace std;
struct node{
string id,name;
int score;
}a[100005];
bool cmp1(node a,node b) {return a.id<b.id;}
bool cmp2(node a,node b){
if(a.name==b.name) return a.id<b.id;
return a.name<b.name;
}
bool cmp3(node a,node b){
if(a.score==b.score) return a.id<b.id;
return a.score<b.score;
}
int main(){
int n,c;
cin>>n>>c;
for(int i=0;i<n;i++) cin>>a[i].id>>a[i].name>>a[i].score;
if(c==1) sort(a,a+n,cmp1);
else if(c==2) sort(a,a+n,cmp2);
else if(c==3) sort(a,a+n,cmp3);
cout<<"Case:"<<endl;
for(int i=0;i<n;i++) cout<<a[i].id<<" "<<a[i].name<<" "<<a[i].score<<endl;
return 0;
}
8🍩1311 继续畅通工程
用kruskal+并查集!
#include<bits/stdc++.h>
using namespace std;
const int N=105;
struct node{
int u,v,w,state;
}edge[N*N];
int fa[N];
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
bool cmp(node a,node b){
if(a.state!=b.state) return a.state>b.state;//先选状态为1的,也就是不用再花钱的路;一定注意这一句,不然会错误
return a.w<b.w;
}
int main()
{
int n;
while(cin>>n)
{
if(n==0) break;
int nn=n*(n-1)/2;
for(int i=0;i<nn;i++)
cin>>edge[i].u>>edge[i].v>>edge[i].w>>edge[i].state;
for(int i=1;i<=n;i++) fa[i]=i;
sort(edge,edge+nn,cmp);
int ans=0,total=0;
for(int i=0;i<nn;i++)
{
int x=find(edge[i].u),y=find(edge[i].v);
if(x!=y)
{
fa[x]=y;
if(edge[i].state==0) ans+=edge[i].w;
total++;
}
}
if(total<n-1) cout<<"no"<<endl;
cout<<ans<<endl;
}
return 0;
}
9🍩1341 还是通畅工程
还是采用kruskal算法+并查集!
#include<bits/stdc++.h>
using namespace std;
const int N=105;
struct node{
int u,v,w;
}edge[N*N];
int fa[N];
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
bool cmp(node a,node b) {return a.w<b.w;}
int main()
{
int n;
while(cin>>n)
{
if(n==0) break;
int nn=n*(n-1)/2;
for(int i=0;i<nn;i++) cin>>edge[i].u>>edge[i].v>>edge[i].w;
for(int i=1;i<=n;i++) fa[i]=i;
sort(edge,edge+nn,cmp);
int ans=0;
for(int i=0;i<nn;i++)
{
int x=find(edge[i].u),y=find(edge[i].v);
if(x!=y)
{
fa[x]=y;
ans+=edge[i].w;
}
}
cout<<ans<<endl;
}
return 0;
}
10🍩1344 最短路径问题
最短路径,先用Floyd,解决不了再考虑其他的!
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int main()
{
int n,m;
int dp[N][N];//dp[i][j]表示i到j的最小长度
int cost[N][N];//cost[i][j]表示i到j的最小花费
while(cin>>n>>m){
if(n==0&&m==0) break;
memset(dp,0x3f,sizeof(dp));
memset(cost,0x3f,sizeof(cost));
for(int i=0;i<m;i++)
{
int a,b,d,p;
cin>>a>>b>>d>>p;
if(d<dp[a][b]){
dp[a][b]=dp[b][a]=d;
cost[a][b]=cost[b][a]=p;
}
else if(d==dp[a][b]&&p<cost[a][b]){//这里注意,更新最小花费
cost[a][b]=cost[b][a]=p;
}
}
for(int k=1;k<=n;k++){//Floyd算法
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dp[i][j]>dp[i][k]+dp[k][j])
{
dp[i][j]=dp[i][k]+dp[k][j];
cost[i][j]=cost[i][k]+cost[k][j];
}
else if(dp[i][j]==dp[i][k]+dp[k][j])//这里注意
{
if(cost[i][j]>cost[i][k]+cost[k][j])//二者长度相等,取最小花费
cost[i][j]=cost[i][k]+cost[k][j];
}
}
}
}
int s,t;
cin>>s>>t;
cout<<dp[s][t]<<" "<<cost[s][t]<<endl;
}
return 0;
}
11🍩1310 奥运排序问题🍰
这也是一道模拟题,就是略微有点麻烦,大家可以多读几遍题!
#include <bits/stdc++.h>
using namespace std;
struct country {
int gold,award,people;
double gproportion,aproportion;
}a[1000005];
int main() {
int n,m;
while(cin>>n>>m){
for(int i=0;i<n;i++){
cin>>a[i].gold>>a[i].award>>a[i].people;
a[i].gproportion=(double)a[i].gold/a[i].people;
a[i].aproportion=(double)a[i].award/a[i].people;
}
//这个排名其实就是看前边有多少人比我分数高
for(int k=0;k<m;k++){
cin>>k;
int rank[4]={1,1,1,1};//四种排序方法得出的排名
for(int i=0;i<n;i++){//遍历所有人比较我和所有人
if(a[k].gold<a[i].gold) rank[0]++;//如果我前边的人这一项的成绩比我高,那么rank就++
if(a[k].award<a[i].award) rank[1]++;
if(a[k].gproportion<a[i].gproportion) rank[2]++;
if(a[k].aproportion<a[i].aproportion) rank[3]++;
}
int way=0;
for(int i=1;i<4;i++){
if(rank[i]<rank[way]) way=i;
}
cout<<rank[way]<<":"<<way+1<<endl;
}
cout<<endl;
}
return 0;
}
12🍩1347 To Fill or Not to Fi🍰
/*
我们假设会经过所有的加油站
我们可以假装持有价格高得油,一旦遇到价格低的就进行替换
在经过加油站的时候,我们补充该加油站的油(注意是假设补充,具体是否补充要看之后有没有遇见更加便宜的油)
比如,我们的油箱在遇到价值4快的加油站时,还剩下2块钱的油和5块钱的油,这说明之前假装补充的5块钱的油
是可以被四块钱的油所替代,因此
我们就可以补充油
注意计算cost的时候要以实际花费的油为准,而不是在补充油的时候进行计算
*/
#include<bits/stdc++.h>
using namespace std;
// double判断相等需要用一个接近无穷小
#define eps 1e-8
//加油站结构体
struct Station{
double price, distance;
}s[200];
bool cmp(Station s1, Station s2){
return s1.distance < s2.distance;
}
int main(){
double cmax, d, davg;
int n;
while (scanf("%lf%lf%lf%d", &cmax, &d, &davg, &n) != EOF){
// 从1开始,较为清晰
for (int i = 1; i <= n; i++){
scanf("%lf%lf", &s[i].price, &s[i].distance);
}
//终点看作特殊的加油站
s[n+1].distance = d;
s[n+1].price = 0;
//注意这里的上下界
sort(s+1, s+1+n+1, cmp);
//双端队列,一方面弹出最低价格的油作为消耗;另一方面弹出最高价格的油作为替换
deque<pair<double, double>> d;
double sumdis = 0., cost = 0.;
if (s[1].distance > eps) printf("The maximum travel distance = 0.00\n");
else {
d.push_back(make_pair(s[1].price, cmax));
for (int i = 2; i <= n+1; i++){
//目标第i个加油站
double sdis = s[i].distance - s[i-1].distance; //距离目标加油站的距离
double need = sdis / davg; //需要使用的油
if (need-cmax > eps){
//油不够用
sumdis += cmax*davg;
printf("%s%.2lf", "The maximum travel distance = ", sumdis);
break;
}
else{
//油够用
sumdis += sdis;
//add是最后要添加的油,计算过程:使用的油+高价的油
double add = need;
while (need > eps){
//这部分是用来计算cost和更新队列原有油信息的
if (d.front().second-need > eps){
//需求小于价格最低的油量,意味着无需弹出队列
cost += need*d.front().first;
d.front().second -= need;
need = 0;
}
else {
//需求大于价格最低的油量,意味着需要弹出队列并进行循环
cost += d.front().first*d.front().second;
need -= d.front().second;
d.pop_front();
}
}
while(!d.empty() && d.back().first > s[i].price){
//这部分使用while循环遍历,找出所有高价油弹出
add += d.back().second;
d.pop_back();
}
//用当前加油站油替换
d.push_back(make_pair(s[i].price, add));
}
//如果此时到达了终点,就打印cost
if (i == n+1) printf("%.2lf\n", cost);
}
}
}
return 0;
}
13🍩1325 xxx定律
一道很简单的模拟题!
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin>>n){
if(n==0) break;
int ans=0;
while(n!=1){
if(n%2==0) n/=2;
else n=(n*3+1)/2;
ans++;
}
cout<<ans<<endl;
}
return 0;
}
14🍩1322 简单计算器🍦
使用stack进行计算器模拟!
#include<bits/stdc++.h>
using namespace std;
int level(char c){
if(c=='*'||c=='/') return 2;
return 1;
}
int main(){
string s;
while(getline(cin,s)){
if(s=="0") break;
stack<double> num;
stack<char> op;
double t=0;
for(int i=0;i<s.size();i++){
if(s[i]>='0'&&s[i]<='9') t=t*10+(s[i]-'0');//if和else可能导致这里的t没有被放入栈中
else if(s[i]!=' '){
num.push(t);
t=0;
while(!op.empty()&&level(op.top())>=level(s[i])){
double a=num.top();
num.pop();
double b=num.top();
num.pop();
char ope=op.top();
op.pop();
if(ope=='+') a=a+b;
else if(ope=='-') a=b-a;
else if(ope=='*') a=a*b;
else a=b/a;
num.push(a);
}
op.push(s[i]);
}
}
num.push(t);//所以这里还要再push一下t
while(!op.empty()){
double a=num.top();
num.pop();
double b=num.top();
num.pop();
char ope=op.top();
op.pop();
if(ope=='+') a=a+b;
else if(ope=='-') a=b-a;
else if(ope=='*') a=a*b;
else a=b/a;
num.push(a);
}
cout<<fixed<<setprecision(2)<<num.top()<<endl;
}
return 0;
}
15🍩1333 开门人和关门人
这道也是简单模拟,就是模拟的过程可能有点复杂,多看几遍题目!
输入:
3 CS301111 15:30:28 17:00:10 SC3021234 08:00:00 11:25:25 CS301133 21:45:00 21:58:40
#include<bits/stdc++.h>
using namespace std;
struct node{
string id,in,out;
}a[1000005];
int main(){
int m;
cin>>m;
for(int i=0;i<m;i++) cin>>a[i].id>>a[i].in>>a[i].out;
string inp=a[0].id,outp=a[0].id;
int h=0,h2=0;
string cur=a[0].in,cur2=a[0].out;
for(int i=0;i<8;i++){
if(cur[i]==':') continue;
h=h*10+(cur[i]-'0');
h2=h2*10+(cur2[i]-'0');
}
//cout<<h<<" "<<h2<<endl;//
int hh=0,hh2=0;
for(int i=1;i<m;i++){
cur=a[i].in;
cur2=a[i].out;
hh=0,hh2=0;
//cout<<i<<":"<<endl;//
for(int j=0;j<8;j++){
if(cur[j]==':') continue;
hh=hh*10+(cur[j]-'0');
hh2=hh2*10+(cur2[j]-'0');
//cout<<h<<" "<<hh<<endl;//
//cout<<h2<<" "<<hh2<<endl;//
}
if(hh<h){
inp=a[i].id;
h=hh;
}
if(hh2>h2){
outp=a[i].id;
h2=hh2;
}
}
cout<<inp<<" "<<outp;
return 0;
}
16🍩1323 A+B加强版
简单模拟!
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
while(getline(cin,s)){
//cout<<s<<endl;//
int ans=0,res=0;
string cur="";
for(int i=0;i<s.size();i++){
if(s[i]=='='){
//cout<<"yes"<<endl;//
//cout<<res<<" "<<ans<<endl;//
if(res==0&&ans==0) return 0;
cout<<res+ans<<endl;
break;
}
else if(s[i]==' '){
//cout<<"yes2"<<endl;//
if(cur=="zero") ans=ans*10+0;
else if(cur=="one") ans=ans*10+1;
else if(cur=="two") ans=ans*10+2;
else if(cur=="three") ans=ans*10+3;
else if(cur=="four") ans=ans*10+4;
else if(cur=="five") ans=ans*10+5;
else if(cur=="six") ans=ans*10+6;
else if(cur=="seven") ans=ans*10+7;
else if(cur=="eight") ans=ans*10+8;
else if(cur=="nine") ans=ans*10+9;
cur="";
}
else if(s[i]=='+'){
//cout<<"yes3"<<endl;//
res=ans;
ans=0;
cur="";
i++;
}
else cur+=s[i];
}
}
return 0;
}
17🍩1316 寻找大富翁
简单的使用sort的问题!
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,a[100005];
while(cin>>n>>m){
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
for(int i=0;i<m;i++) cout<<a[n-1-i]<<" ";
cout<<endl;
}
return 0;
}
18🍩1328 又一版A+B🍰
简单模拟+进制转换!
#include<bits/stdc++.h>
using namespace std;
int main(){
int m,a,b;
while(cin>>m)
{
if(m==0)
return 0;
cin>>a>>b;
vector<int> a1;
vector<int> b1;
//改成m进制格式
if(a==0) a1.push_back(0);
while(a>0)
{
a1.push_back(a%m);
a/=m;
}
if(b==0) b1.push_back(0);
while(b>0)
{
b1.push_back(b%m);
b/=m;
}
int size=max(a1.size(),b1.size());
//位数补齐
a1.resize(size,0);
b1.resize(size,0);
//计算A+B
vector<int> res(size,0);
int flag=0;//进位标识
for(int i=0;i<res.size();i++)
{
int temp=flag+b1[i]+a1[i];
flag=temp/m;
res[i]=temp%m;
}
if(flag>0)//最终还有进位,也就是超出原来的size大小了
res.push_back(flag);
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
}
return 0;
}
19🍩1309 欧拉回路🍰
存在欧拉回路:连通+所有顶点的度为偶数!
#include <bits/stdc++.h>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VII;
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==0) break;
VII vec(n+1,VI(n+1,0));
int a,b;
for(int i=0;i<m;i++)
{
cin>>a>>b;
if(a==b) continue;
vec[a][b]=vec[b][a]=1;
}
int flag=0;
for(int i=1;i<=n;i++)
{
int degree=0;
for(int j=1;j<=n;j++){
if(vec[i][j]) degree++;
}
if(degree%2!=0)//奇数
{
flag=1;
break;
}
}
if(flag) cout<<"0"<<endl;
else cout<<"1"<<endl;
}
return 0;
}
20🍩1315 找出直系亲属🍰
使用二叉树记录亲属关系!
//摘自N诺用户:lielie
#include<bits/stdc++.h>
using namespace std;
struct Parents{
char p1;
char p2;
};
map<char,Parents> tree;
//对比parent是否和child是relation关系
string findRelation(char child,char parent,string relation=""){
if (tree.count(child)==0) return "-";//没有这个child
//有这个child,获得他的双亲
Parents parents=tree[child];
if(parents.p1==parent||parents.p2==parent){//这个人是该child的父母
return relation.empty()?"parent":relation;//
}
//不是直接的父母亲,找直接父母亲的父母亲
string relation1=findRelation(parents.p1,parent,relation.empty()?"grandparent":"great-"+relation);
if(relation1!="-") return relation1;
string relation2=findRelation(parents.p2,parent,relation.empty()?"grandparent":"great-"+relation);
if(relation2!="-") return relation2;
return "-";
}
string findChildRelation(char parent,char child,string relation=""){
if(tree.count(child)==0) return "-";
Parents parents=tree[child];
if(parents.p1==parent||parents.p2==parent){
return relation.empty()?"child":relation;
}
string relation1=findChildRelation(parent,parents.p1,relation.empty()?"grandchild":"great-"+relation);
if(relation1!="-") return relation1;
string relation2=findChildRelation(parent,parents.p2,relation.empty()?"grandchild":"great-"+relation);
if(relation2!="-") return relation2;
return "-";
}
int main(){
int n,m;
while(cin>>n>>m){
tree.clear();
for(int i=0;i<n;i++){
string s;
cin>>s;
Parents parents={s[1],s[2]};
tree[s[0]]=parents;
}
for(int i=0;i<m;i++){
string s;
cin>>s;
string parentToChild=findRelation(s[1],s[0]);
if(parentToChild!="-"){
cout<<parentToChild<<endl;
continue;
}
string childToParent=findChildRelation(s[1],s[0]);
if(childToParent!="-"){
cout<<childToParent<<endl;
continue;
}
cout<<"-"<<endl;
}
}
return 0;
}
创作不易,点个赞吧~感兴趣的宝子欢迎关注本专栏和我们一起学习机试内容哦~
宝子们学习辛苦啦,休息下,我们下部分再见!👋( •̀ ω •́ )✧ ~
大家还想看哪个学校的机试题目,评论区告诉我~~~