10.10天梯賽補題
阿新 • • 發佈:2020-10-11
7-1估值一億的AI核心程式碼(20分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
解題思路:字串函式應用
string.find("xx") string::npos s.replace(位置,長度,替換為什麼) string.erase(pos,n) //刪除從pos開始的n個字元 string.erase(0,1); 刪除第一個字元 string.erase(pos) //刪除pos處的一個字元(pos是string型別的迭代器) string.erase(first,last) //刪除從first到last中間的字元(first和last都是string型別的迭代器) ispunct() //檢測一個字元是否是標點符號,返回真or假 string.find("xx",從什麼位置開始)
#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; static const int MAX_N = 15; string str; bool judge(int pos, int p, int len) { /*越界判斷*/ if(pos + p < len && pos - 1 >= 0) return (!isalnum(str[pos - 1]) && !isalnum(str[pos + p]));估值一億的AI核心程式碼else if(pos - 1 >= 0) return (!isalnum(str[pos - 1])); else if (pos + p < len) return (!isalnum(str[pos + p])); else return true; } int main() { int t; scanf("%d", &t); getchar(); while (t--) { getline(cin, str); cout << str << endl;int len = str.length(); while (len > 1 && str[0] == ' ') { //去掉行前空格 str.erase(0, 1); len--; } int i = len - 1; while (i >= 0 && str[i] == ' ') { //去掉行末空格 str.erase(i, 1); --i; } i = 0; len = str.length(); for (; i < len; ++i) { while (str[i] == ' ') { //去掉單詞間的多餘空格 if (i + 1 < len && !isalnum(str[i + 1])) { //這裡不能直接判斷是空格,因為是標點符號的話,空格也需要去掉 str.erase(i, 1); len--; } else break; } if(str[i] != 'I' && str[i] >= 'A' && str[i] <= 'Z') //轉小寫 str[i] += 32; else if (str[i] == '?') str[i] = '!'; } for (i = 0; i < len; ++i) { if (str[i] == 'I' && judge(i, 1, len)) str.replace(i, 1, "you"); /*擷取字元,注意判斷,不然會陣列越界*/ else if (i + 1 < len && str.substr(i, 2) == "me" && judge(i, 2, len)) str.replace(i, 2, "you"); else if (i + 6 < len && str.substr(i, 7) == "can you" && judge(i, 7, len)) str.replace(i, 7, "I can"); else if (i + 8 < len && str.substr(i, 9) == "could you" && judge(i, 9, len)) str.replace(i, 9, "I could"); len = str.length(); } printf("AI: "); cout << str << endl; } return 0; }
7-3N個數求和(20分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
在實驗室做出來了就不多贅述了
#include<stdio.h> #include<math.h> #include<string.h> #define Q 1000000007 #define ll long long int int ys(ll a,ll b) { ll i; while(b!=0) { i=a%b; a=b; b=i; } return a; } int main() { ll a[150]; ll b[150]; int n; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%lld/%lld",&a[i],&b[i]); } ll sum1=a[0]; ll sum2=b[0]; int s=ys(sum1,sum2); sum1/=s; sum2/=s; for(int i=1; i<n; i++) { s=ys(sum2,b[i]); sum1=sum1*(b[i]/s)+a[i]*(sum2/s); sum2=sum2*b[i]/s; s=ys(sum1,sum2); sum1/=s; sum2/=s; } ll t=sum1/sum2; sum1=sum1%sum2; if(sum2<0) { sum1=-sum1; sum2=-sum2; } if(sum1==0) printf("%lld\n",t); else if(t==0) printf("%lld/%lld\n",sum1,sum2); else printf("%lld %lld/%lld\n",t,sum1,sum2); return 0; }
7-9名人堂與代金券(25分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
解題思路:採用結構體,注意相同的排名按照字母表排序,後續的排名順延就行
#include<iostream> #include<algorithm> using namespace std; struct node{ int rank;//排名; string str; int grade; }person[10005]; bool cmp(struct node p1,struct node p2) { if(p1.grade != p2.grade) { return p1.grade>p2.grade;//非升序排列; } else if(p1.grade == p2.grade) { return p1.str<p2.str;//按賬號的字母升序輸出; } } int main() { int n,g,k,i,j,sum=0,count=1;//n指的是學生總數,g指的是等級分界線,k指的是進入名人堂的最低名次; cin>>n>>g>>k; for(i=0;i<n;i++) { cin>>person[i].str>>person[i].grade; if(person[i].grade>=g){ sum = sum + 50; } else if(person[i].grade>=60&&person[i].grade<g){ sum = sum + 20; } } //PAT 代金券的總面值 cout<<sum<<endl; sort(person,person+n,cmp); person[0].rank = 1;// count=1; //當成績相同時,排名一樣 for(i=1;i<n;i++) { count++; if(person[i].grade == person[i-1].grade) { person[i].rank = person[i-1].rank; } else { person[i].rank = count; } } //輸出名次在<=k範圍之內的同學資訊!!!! for(i=0;i<n;i++) { if(person[i].rank<=k) { cout<<person[i].rank<<" "<<person[i].str<<" "<<person[i].grade<<endl; } } return 0; }
7-10 連結串列去重 (25分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
解題思路:題目要求刪除鍵值的絕對值有重複的結點,然後先輸出刪除後的連結串列,再輸出被刪除的連結串列
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn = 1e5; struct Node{ int address; int key; int next; int num; }node[maxn]; bool vis[maxn]; bool cmp(Node a,Node b){ return a.num<b.num; } int main() { int head,n,a; scanf("%d%d",&head,&n); int k1=0,k2=0; for(int i=0;i<maxn;i++){ node[i].num=2*maxn; } for(int i=0;i<n;i++){ scanf("%d",&a); scanf("%d%d",&node[a].key,&node[a].next); node[a].address=a; } for(int i=head;i!=-1;i=node[i].next){ if(!vis[abs(node[i].key)]){ vis[abs(node[i].key)]=true; node[i].num=k1; k1++; }else{ node[i].num=maxn+k2; k2++; } } sort(node,node+maxn,cmp); int k=k1+k2; for(int i=0;i<k;i++){ if(i!=k1-1&&i!=k-1){ printf("%05d %d %05d\n",node[i].address,node[i].key,node[i+1].address); }else{ printf("%05d %d -1\n",node[i].address,node[i].key); } } return 0; }
7-11部落(25分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
解題思路:用了並查集,存點的時候有一點是用了set存點,直接去除重複點來計算共有多少結點。易錯易超時的地方就是find函式一定要用優化版本的find函式,不然會超時。
#include <bits/stdc++.h> using namespace std; int fa[10005], flag[10005]; set<int> s; int find(int x){ if(fa[x]==x){ return x; }else{ return fa[x] = find(fa[x]); } } void Union(int a, int b){ int fathera = find(a); int fatherb = find(b); if(fathera!=fatherb){ fa[fatherb] = fathera; } } int main() { ios::sync_with_stdio(false); int n, num=0, q, q1, q2; cin>>n; for(int i=0;i<10005;i++){ fa[i] = i; flag[i] = 0; } for(int i=0;i<n;i++){ int k, p[10005]; cin>>k>>p[0]; s.insert(p[0]); for(int j=1;j<k;j++){ cin>>p[j]; s.insert(p[j]); Union(p[0], p[j]); } } set<int>::iterator it; for(it=s.begin();it!=s.end();it++){ if(flag[find(*it)]==0){ num++; flag[find(*it)] = 1; } } cout<<s.size()<<" "<<num<<endl; cin>>q; for(int i=0;i<q;i++){ cin>>q1>>q2; if(find(q1)==find(q2)){ cout<<"Y"<<endl; }else{ cout<<"N"<<endl; } } return 0; }
7-12月餅(25分)
題目連結:https://pintia.cn/problem-sets/1314102638464851968/problems/1314102915477659648
解題思路:用了結構體,計算一下每種月餅的單價從高往低誰單價高先賣誰,資料用double,注意小數點。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; struct mooncake //用結構體可以方便對單價排序,分開定義陣列會打亂順序 { double knum; //都有可能是小數 double pnum; double anum; }; bool cmp(mooncake a,mooncake b) { return a.anum>b.anum; } int main() { int N,D; cin>>N>>D; mooncake mk[1001]; for(int i=0;i<N;i++) cin>>mk[i].knum; for(int i=0;i<N;i++) cin>>mk[i].pnum; for(int i=0;i<N;i++) mk[i].anum=mk[i].pnum/mk[i].knum; sort(mk,mk+N,cmp); int i=0; double sum=0; while(D!=0) { if(D<=mk[i].knum) { sum+=mk[i].anum*D; D=0; } else { sum+=mk[i].pnum; D-=mk[i].knum; } i++; } printf("%.2f",sum); //輸出帶格式,使用printf更方便 }