A. Electric Bill
題意:這一題比較簡單,相當于小學的分組函式的計算電力費用的的題型,
題解:簽到題,
代碼:
#include<iostream> #include<cstring> #include<algorithm> #define ll long long using namespace std; int main(){ int F,E; int n; cin>>F>>E; cin>>n; int temp; while(n--){ cin>>temp; int ans=0; cout<<temp<<" "; if(temp<=1000){ cout<<temp*F<<endl; }else{ cout<<1000*F+(temp-1000)*E<<endl;; } } return 0; }
B. Simplified Keyboard
題意:這一題的大概意思就是新組合的字母的排列,給出了字母間相鄰的定義,題目給出兩個字串,要你在題目要求的情況下判斷這兩個字串屬于哪一種型別,
題解:簡單簽到題,根據題意對那個字串進行分情況判斷,在判斷兩個字符是否是“鄰居”時候,可利用:
net[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}};
進行每個方向的判斷,
代碼:
#include<iostream> #include<cstring> #include<algorithm> #define ll long long using namespace std; char arr[3][9]= {{'a','b','c','d','e','f','g','h','i'}, {'j','k','l','m','n','o','p','q','r'}, {'s','t','u','v','w','x','y','z','#'} }; int net[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,-1},{-1,1}}; int check(int r,int c){ if(r>=0&&r<3){ if(r==2){ if(c>=0&&c<=7){ return 1; } }else{ if(c>=0&&c<=8){ return 1; } } } return 0; } int app(char a/*主體*/,char b/*客體*/){//是否是相鄰的 int x,y; for(int i=0;i<3;i++){//找到 本尊的位置 for(int j=0;j<9;j++){ if(arr[i][j]==a){ x=i; y=j; break; } } } int d=0; for(int i=0;i<8;i++){ int dx=x+net[i][0]; int dy=y+net[i][1];//這是下一個坐標 if(check(dx,dy)/*判斷坐標是否合法*/){ if(arr[dx][dy]==b){//相等 d=1; break; }else{//不相等 } } } return d; } int main() { int n; string str1,str2; cin>>n; while(n--) { cin>>str1>>str2; int len1=str1.length(); int len2=str2.length(); if(len1!=len2) { cout<<3<<endl; } else { //兩者的長度相同 在這里,可能輸出 1 ,可能輸出 2 ,可能輸出 3 int f=1; for(int i=0; i<len1; i++) { if(str1[i]!=str2[i]) { //出現了不相等的 f=0; } } if(f==1) { cout<<1<<endl; } else { //可能輸出 2 ,可能輸出 3 //以 str1 為基礎,尋找它的鄰居,或和它本身相鄰 int g=1;//記錄是否找到 鄰居 for(int i=0; i<len1; i++) { if(str1[i]==str2[i]) { //若兩者相等 } else { //兩者不相等,找兩者相鄰 g=app(str1[i],str2[i]); if(!g) { break; } } } if(g) { cout<<2<<endl; } else { cout<<3<<endl; } } } } return 0; }
C. Singin' in the Rain
題意:題目的大概意思就是:給出一張CD的歌曲數目,一串喜歡歌曲的序列,通過按下“下一曲”、“上一曲”的按鍵來改變曲目的播放順序,要你求,最少要你按多少次才能達到要求,
題解:注意播放順序的改變規則即可,模擬,
#include<iostream> #include<cstring> #include<algorithm> #define ll long long using namespace std; int main(){ ll n;//樣例的數量 cin>>n; ll t,s; while(n--){ cin>>t/*一張CD上的歌曲的總數*/>>s/*喜歡歌曲的數量*/; ll num[10000]={0}; for(ll i=0;i<s;i++){ cin>>num[i];//輸入喜歡歌曲的序號 }//序號輸入完畢,下面開始處理啊資料 ll ans=0;//存盤的是答案 ll tt=num[0];//當前播放歌曲的位置 //當第一首歌曲播放完之后, ll net;//下一首要播放的歌曲 for(ll i=1;i<s;i++){ net=num[i];//這是下一首 if(net<num[i-1]){//在它之前 ans=ans+min(num[i-1]-net+1,t-num[i-1]-1+net); }else if(net>num[i-1]){//在之后 if(net-num[i-1]==1){//不需要按 }else{//需要按 ans=ans+min(net-num[i-1]-1,num[i-1]+(t-net+1)); } }else if(net==num[i-1]){//下一首播放的歌曲和上一首播放的歌曲一樣 ans++;//往后在按一次 “后退鍵 ” tt=net;//在一次到達原位置 } //當前歌曲播放完 } cout<<ans<<endl; } return 0; }
D. Editor Navigation
題意:這題是一個最短路的問題,給你兩個點的坐標,要你求移動最少的次數到達目的地,創新的是它給出的不是一個“規矩”的矩陣,移動的規則也和正常的題目有點不同,
題解:BFS求最短路,但要注意在確定它的下一個坐標的時候和正常的題型不同,最短路的步數和點的坐標一起整合在一個結構體中,
代碼:
#include<iostream> #include<cstring> #include<queue> #include<algorithm> using namespace std; int T,n; int str,stc,enr,enc; int num[900]={0}; int vis[900][900]={0}; struct node{ int r,c,cnt; }; int net[4][2]= {-1,0,1,0,0,-1,0,1}; void bfs(){ queue<node> q; q.push({str,stc,0}); vis[str][stc]=1; memset(vis,0,sizeof(vis)); while(!q.empty()){ node p=q.front(); q.pop(); int r=p.r; int c=p.c; int cnt=p.cnt; if(r==enr&&c==enc){//找到目標點 printf("%d\n",cnt); return ; } for(int i=0;i<4;i++){//遍歷四個方向 int dr=r+net[i][0]; int dc=c+net[i][1]; if(dr>=1&&dr<=n){ if(i==0||i==1){//上下移動 if(dc<=num[dr]&&!vis[dr][dc]){//直來支直去 vis[dr][dc]=1; q.push({dr,dc,cnt+1}); } if(dc>num[dr]&&!vis[dr][num[dr]]){ vis[dr][num[dr]]=1; q.push({dr,num[dr],cnt+1}); } }else{//左右移動 if(dc==-1&&i==2&&r-1>=1){ int tr=r-1; int tc=num[tr]; if(!vis[tr][tc]){ q.push({tr,tc,cnt+1}); vis[tr][tc]=1; } } if(dc==num[r]+1&&i==3&&r+1<=n){//這是坐標向右移動,處在最后的一個點移動到下一行的的第一個字符 int tr=r+1; int tc=0; if(!vis[tr][tc]){ vis[tr][tc]=1; q.push({tr,tc,cnt+1}); } } if(dc>=0&&dc<=num[dr]&&!vis[dr][dc]){ vis[dr][dc]=1; q.push({dr,dc,cnt+1}); } } } } } } int main(){ cin>>T; while(T--){ cin>>n;/*總共有幾行*/ for(int i=1;i<=n;i++){ cin>>num[i]; } cin>>str>>stc>>enr>>enc; bfs(); } return 0; }
E. Simple Darts
題意:這是一道反三角函式利用的題目,給你一個圓盤,將其劃分為W個區域,每個區域的得分各不相同,向其投向n個鏢,求出最終得分,
題解:通過計算點到原點的距離,可以判斷它屬于那個環內,通過計算點與原點的連線和X軸的夾角可以判斷它屬于內閣楔形--這個的計算方法是:
double gf=atan((y*1.0)/x)*(180.0*1.0/pi);//算出應有的角度
gf是指點(x,y)與x軸所夾的銳角,但要注意當回傳的是一個負值時,可以通過增加180度or360度來進行調整,具體增加多少,要根據點所處的象限來判斷,
代碼:
#include<iostream> #include<cstring> #include<algorithm> #include<math.h> #define ll long long double pi= 3.1415926535898 ; using namespace std; double app(double x,double y){ return sqrt(x*x+y*y); } int main(){ int n,t; int w,b,d,s; double x,y; cin>>n;//樣例的數量 while(n--){ cin>>w>>b>>d>>s; //圓形平均分成了 w 份 double cc=360*1.0/w;//每一份的度數 double tch[25]={0}; tch[1]=cc; for(int i=2;i<=w;i++){ tch[i]=tch[i-1]+cc; } cin>>t; int ans=0;//存盤最終得分 //邊輸入,邊處理 for(int i=0;i<t;i++){ scanf("%lf %lf",&x,&y);//輸入兩個點的坐標 double len1=app(x,y); if(len1<=b){//位于 第一個小圓環中 ans=ans+50; }else{ int f=0;//這是放大的倍數 if(len1>b&&len1<d){ f=2; }else if(len1>d&&len1<s){ f=1; } //下面關鍵是判斷位于哪一個楔形內 double gf=atan((y*1.0)/x)*(180.0*1.0/pi);//算出應有的角度 //判斷是否要選裝 if(x<0&&y>0){//二象限 gf=180+gf; } if(x<0&&y<0){//三象限 gf=gf+180; } if(x>0&&y<0){ gf=gf+360; } int gg=0; for(int i=1;i<=w;i++){ if(gf<tch[i]){//在這之中 gg=i; break; } } ans=ans+gg*f; } } cout<<ans<<endl; } return 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/40790.html
標籤:C++
下一篇:加邊的無向圖--并查集
