浙大PAT考試1013~1016(最傷的一次。。)
我能說我1016WA了幾天都不得最後還是拿別人代碼交的麽。
。。
真心找不到那個神數據。。
。
自己把整個程序的流程都畫出來了。細致推敲是木有問題的啊。。。
題目地址:點擊打開鏈接
先從1013開始介紹。
題目大意:給你n個城市,m條路,k個詢問。每次詢問。是假設沒有城市q1,,,qk其它城市鏈接在一起至少須要多少條路。
簡單的並查集問題。對節點qi無論,其它的點用並查集。我們所要求的就是有多少個分量。ans個分量則須要ans-1條路就可以。詳見代碼:
AC代碼:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; const int maxn=1005; struct node { int x; int y; }nod[maxn*maxn]; int fa[maxn]; void init() { for(int i=1;i<=1000;i++) fa[i]=i; } int find1(int p) { if(fa[p]!=p) fa[p]=find1(fa[p]); return fa[p]; } void merge1(int p,int q) { p=find1(p); q=find1(q); if(p!=q) fa[p]=q; } int main() { int n,m,k; int i; while(cin>>n>>m>>k) { for(i=0;i<m;i++) scanf("%d%d",&nod[i].x,&nod[i].y); int cur; while(k--) { scanf("%d",&cur); int res=0; init(); for(i=0;i<m;i++) { int p,q; p=nod[i].x,q=nod[i].y; if(p==cur||q==cur) continue; merge1(p,q); } for(i=1;i<=n;i++) { if(i==cur) continue; if(fa[i]==i) res++; } printf("%d\n",res-1); } } return 0; } /* 3 2 3 1 2 1 3 1 2 3 */
1014:
題目大意:題目有點麻煩,意思是在取錢之類的背景下。。
有n個窗體,每一個窗體黃線裏面最多容下的人數m。k個客戶。q個查詢。
然後依次給出你k個客戶的在櫃臺的處理時間,然後q個查詢,每次查詢編號為qi的客戶處理完之後的時間。時間是08:00開始,17:00結束。
註意,這裏有個bug。17:00結束是假設你在17:00之前還在櫃臺前面,就會被處理。
解題思路:最開始我們先把隊伍一個一個排好,由於題目說的意思是每次都會排在最少人數的隊列中,假設隊列人數有一樣的。選編號小的。那麽我們最開始處理的時候就先把n*m容量之類的排好,一個一個按著隊列排。然後出一個進一個,依次模擬,詳見代碼:
AC代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> using namespace std; int n,m,k,peo,ccnt; struct node { int t; int index; } nod[1005]; queue <node> mq[25]; int res[1005]; int mp[25]; void debug() { for(int i=1; i<=2; i++) { node x=mq[i].front(); cout<<x.t<<" "; mq[i].pop(); x=mq[i].front(); cout<<x.t<<endl; } } void init() //初始化,先預先站隊 { int i,j; for(int i=1;i<=1000;i++) res[i]=10000; for(i=1; i<=20; i++) { while(!mq[i].empty()) mq[i].pop(); } int cnt=0; for(i=1; i<=k; i+=n) { for(j=0; j<n; j++) { if(cnt==n*m) { //debug(); peo=cnt+1; return; } mq[j+1].push(nod[i+j]); cnt++; } } peo=cnt+1; //peo代表下一個排隊人的編號 return; } void resolve() //時間到了16:59,僅僅有reserved的人才幹夠完畢交易 { int i; for(i=1; i<=n; i++) { if(!mq[i].empty()) { node x=mq[i].front(); res[x.index]=ccnt+mp[i]; } } return; } void solve() { ccnt=1; for(int i=1; i<=n; i++) { if(!mq[i].empty()) { node x=mq[i].front(); mp[i]=x.t; } } while(1) { if(ccnt==540) { ccnt--; resolve(); //時間已到。僅僅處理在隊首的 break; } for(int i=1; i<=n; i++) { if(!mq[i].empty()) { mp[i]--; if(mp[i]==0) //假設某個隊伍有人完畢交易,立刻填充人進來 { node x=mq[i].front(); mq[i].pop(); res[x.index]=ccnt; if(peo<=k) mq[i].push(nod[peo++]); if(!mq[i].empty()) { node x=mq[i].front(); mp[i]=x.t; } } } } ccnt++; } } int main() { int q,i; while(cin>>n>>m>>k>>q) { for(i=1; i<=k; i++) { cin>>nod[i].t; nod[i].index=i; } init(); solve(); //cout<<res[6]<<endl; int x; while(q--) { cin>>x; if(res[x]==10000) puts("Sorry"); else printf("%02d:%02d\n",(res[x]+480)/60,(res[x]+480)%60); } } return 0; } /* 2 2 7 5 1 2 6 4 3 534 2 3 4 5 6 7 */
1015:
題目大意:給你兩個數n。b,我們記還有一個數是m,將n轉換為b進制然後再倒轉再轉換成10進制變成m,假設n和m都是素數,那麽yes,否則no。
直接模擬就好。
AC代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> using namespace std; const int maxn=1005; int a[maxn]; int base; int isprime(int x) { if(x==1||x==0) return 0; for(int i=2;i<=sqrt(x+0.5);i++) { if(x%i==0) return 0; } return 1; } int verse(int x) { int p=x; int cnt=0; while(p) { a[cnt++]=p%base; p/=base; } int ans=0; for(int i=0;i<cnt;i++) { ans=ans*base+a[i]; } return ans; } int main() { int x; while(cin>>x&&x>=0) { cin>>base; int y=verse(x); //cout<<y<<endl; if(isprime(x)&&isprime(y)) puts("Yes"); else puts("No"); } return 0; } /* 73 10 23 2 23 10 -2 */
1016:
由於這個1016。真的被傷了。。。。
題目大意:主題是算話費的,先給你24小時每小時內每分鐘的資費。各自是00:00-01:00,01:00-02:00的每分鐘話費,單位是美分,然後給你n個電話記錄,每條記錄會實username。月:天:時:分。然後是一個狀態。online表示打電話。offline表示掛電話。
所以我們要排序匹配。
而題目中說了保證每一個人的記錄是一個月份內的。
而且假設某人的記錄沒一個能匹配的話就不打印他的賬單。
預計是自己的代碼寫挫了。。。
(15分/25分)代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> #include<algorithm> #define ll long long using namespace std; const double eps=1e-10; int rate[26]; //每小時裏1分鐘的價錢 int n; //多少個記錄 struct node { char name[25]; char time[25]; int month; int day; int hour; int minu; int fla; } bill[1005]; struct nod { char ans1[25]; char ans2[25]; int curt; double mon; } ans[1005]; int cmp(node p1,node p2) { if(strcmp(p1.name,p2.name)<0) return 1; else if(strcmp(p1.name,p2.name)==0&&strcmp(p1.time,p2.time)<0) return 1; return 0; } double cal1(int day,int hour,int minu) //計算money { double ans=0; ans+=(double)day*rate[25]*60; for(int i=1; i<hour+1; i++) ans+=rate[i]*60; ans+=(double)rate[hour+1]*minu; return ans/100.0; } int cal2(int day,int hour,int minu) //計算時間 { return day*24*60+hour*60+minu; } void solve() { char ansname[25]; int cnt; int month; cnt=0; int p=0; //cout<<bill[0].time<<" "<<bill[0].month<<endl; //for(int i=0; i<n; i++) //cout<<i<<" "<<bill[i].name<<" "<<bill[i].time<<" "<<bill[i].fla<<endl; while(p<n) //最開始先找一個online的位置p { if(bill[p].fla==1) { strcpy(ansname,bill[p].name); month=bill[p].month; p++; break; } else p++; } //cout<<ansname<<" "<<month<<endl; //cout<<p<<endl; double total=0; //記錄一個月的花費 int flag=1; //flag=1代表有online, //puts("fuck1"); while(p<n) { //cout<<p<<"****"<<endl; if(strcmp(ansname,bill[p].name)!=0) { //cout<<"????
"<<cnt<<endl; if(cnt>0) { printf("%s %02d\n",ansname,month); for(int i=0; i<cnt; i++) { printf("%s %s %d $%.2f\n",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon); } printf("Total amount: $%.2f\n",total); total=0; cnt=0; } flag=0; while(p<n) //剛處理完一個人的,尋找下一個online的 { if(bill[p].fla==1) { strcpy(ansname,bill[p].name); month=bill[p].month; p++; flag=1; break; } else p++; } } else //說明當前是一個月一個人的。
{ if(bill[p].fla==0&&flag) //開始計算 { ans[cnt].curt=cal2(bill[p].day,bill[p].hour,bill[p].minu)- cal2(bill[p-1].day,bill[p-1].hour,bill[p-1].minu); ans[cnt].mon=cal1(bill[p].day,bill[p].hour,bill[p].minu)- cal1(bill[p-1].day,bill[p-1].hour,bill[p-1].minu); total+=ans[cnt].mon; char tmp1[25],tmp2[25]; for(int i=0; i<8; i++) { tmp1[i]=bill[p-1].time[i+3]; tmp2[i]=bill[p].time[i+3]; } tmp1[8]=tmp2[8]-‘\0‘; strcpy(ans[cnt].ans1,tmp1); strcpy(ans[cnt++].ans2,tmp2); p++; flag=0; //cout<<p<<" hhe"<<endl; } else { flag=0; if(bill[p].fla==1) { flag=1; } p++; } } } if(cnt>0) { //puts("fuck"); printf("%s %02d\n",ansname,month); for(int i=0; i<cnt; i++) { printf("%s %s %d $%.2f\n",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon); } printf("Total amount: $%.2f\n",total); total=0; cnt=0; } } int main() { int i; while(cin>>rate[1]) { rate[25]=0; rate[25]+=rate[1]; for(i=2; i<=24; i++) { cin>>rate[i]; rate[25]+=rate[i]; //rate[25]是24小時的總和 } char tmp1[25]; cin>>n; for(i=0; i<n; i++) { cin>>bill[i].name>>bill[i].time>>tmp1; if(strcmp(tmp1,"on-line")==0) //假設是1,表示接通,不是的話就是掛斷 bill[i].fla=1; else bill[i].fla=0; strcpy(tmp1,bill[i].time); bill[i].month=(tmp1[0]-‘0‘)*10+(tmp1[1]-‘0‘); bill[i].day=(tmp1[3]-‘0‘)*10+(tmp1[4]-‘0‘); bill[i].hour=(tmp1[6]-‘0‘)*10+(tmp1[7]-‘0‘); bill[i].minu=(tmp1[9]-‘0‘)*10+(tmp1[10]-‘0‘); } sort(bill,bill+n,cmp); solve(); } return 0; } /* 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 10 CYLL 01:01:06:01 on-line CYLL 01:28:16:05 off-line CYJJ 01:01:07:00 off-line CYLL 01:01:08:03 off-line CYJJ 01:01:05:59 on-line aaa 01:01:01:03 on-line aaa 01:02:00:01 on-line CYLL 01:28:15:41 on-line aaa 01:05:02:24 on-line aaa 01:04:23:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 4 CYJJ 01:01:07:00 off-line CYJJ 01:01:05:59 on-line CYJJ 01:01:05:00 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 2 CYJJ 01:01:08:00 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 2 CYJJ 01:01:07:58 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 18 CYLL 01:01:06:01 on-line CYLL 01:01:07:00 off-line CYLL 01:01:08:03 on-line CYLL 01:01:08:09 off-line CYLL 01:01:08:09 on-line CYLL 01:02:00:01 off-line CYLL 01:28:15:41 on-line CYLL 01:29:02:24 on-line CYLL 01:30:23:59 off-line CYLL 01:30:24:59 off-line CYLL 01:30:25:00 off-line CYLL 01:30:25:25 off-line MQ 01:01:06:01 on-line MQ 01:02:03:04 on-line MQ 01:03:04:05 on-line MQ 01:03:04:06 off-line YF 01:02:03:04 on-line YF 01:02:03:05 on-line all dates will be within a single month. */
網上有大神的滿分代碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char name[22];//名字 int month;//月份 int day;//天 int hour;//時 int minute;//分 char tag[10];//on-line or off-line }record; int n; record *rd; int rate[24];//費率 int count, start;//記錄當前處理的這個用戶的記錄數目。和當前這個用戶的第一條記錄位置 double totalCharge;//該用戶該月的費用合計 double charge(int sday, int shour, int sminute, int eday, int ehour, int eminute)//計算一條有效電話記錄的時長和費用。並返回費用 { double cost = 0; long time = 0; while(sday < eday)//先讓天相等 { time += (60 - sminute); cost += (60 - sminute) * rate[shour]; sminute = 0; shour ++;//分化成0。時加1 time += 60 * (24 - shour); while(shour < 24) { cost += 60 * rate[shour]; shour ++; } shour = 0; sday ++;//時化成0。天加1 }//天此時相等,時分為00:00 while(shour < ehour)//再讓時相等 { time += (60 - sminute); cost += (60 - sminute) * rate[shour]; sminute = 0; shour ++; } time += (eminute - sminute); cost += rate[ehour] * (eminute - sminute); printf("%ld $%.2lf\n", time, cost / 100); return cost / 100; } void totalCount()//數出當前要處理的客戶的總記錄數目 { int i; for(i = start + 1; i < n; i ++) { if(strcmp(rd[i].name, rd[i - 1].name) != 0) { break; } else { count ++; } } } int comp_name(const void *a, const void *b) { record c = *(record *)a; record d = *(record *)b; if(strcmp(c.name, d.name) <= 0) return -1; else return 1; } int comp_time(const void *a, const void *b) { record c = *(record *)a; record d = *(record *)b; if(c.day < d.day) return -1; else if(c.day > d.day) return 1; else { if(c.hour < d.hour) return -1; else if(c.hour > d.hour) return 1; else { if(c.minute < d.minute) return -1; else return 1; } } } int main() { int i; int flag;//1應該出現offline, 0應該出現online int onpos;//記錄近期有效的on-line記錄位置,為了算出charge int sign;//0表示該客戶名字和月份還沒有輸出。1表示已輸出 while(scanf("%d", &rate[0]) != EOF) { for(i = 1; i < 24; i ++) { scanf("%d", &rate[i]); } scanf("%d", &n); rd = (record *)malloc(n * sizeof(record)); for(i = 0; i < n; i ++) { scanf("\n%s %d:%d:%d:%d %s", rd[i].name, &rd[i].month, &rd[i].day, &rd[i].hour, &rd[i].minute, rd[i].tag); } qsort(rd, n, sizeof(record), comp_name);//先將記錄按字母表順序分類 count = 1; start = 0; totalCount(); sign = 0; while(start < n)//整個記錄表還沒處理完 { qsort(rd + start, count, sizeof(record), comp_time); flag = 0; totalCharge = 0; for(i = start; i < start + count; i ++)//處理該客戶 { if(flag == 0)//期待出現online,假設是offline跳過 { if(rd[i].tag[1] == ‘f‘)//off-line { continue; } else//on-line { onpos = i; flag = 1; } } else//期待出現offline,假設是online則更新onpos { if(rd[i].tag[1] == ‘n‘)//on-line { onpos = i; } else//off-line { if(sign == 0) { printf("%s %02d\n", rd[start].name, rd[start].month); sign = 1; } printf("%02d:%02d:%02d %02d:%02d:%02d ", rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute); totalCharge += charge(rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute); flag = 0; } } } if(sign == 1) { printf("Total amount: $%.2lf\n", totalCharge); } start += count; count = 1; totalCount(); sign = 0; } } return 0; }
真心被玩兒出內傷了。
。
。
。
浙大PAT考試1013~1016(最傷的一次。。)