1. 程式人生 > 其它 >1.24UPC寒假個人訓練第12場

1.24UPC寒假個人訓練第12場

技術標籤:UPC專欄

1.24UPC寒假個人訓練第12場(H L M還沒補)

問題 A: 馬攔過河卒

題目描述
棋盤上A點有一個過河卒,需要走到目標B點。卒行走的規則:可以向下、或者向右。同時在棋盤上C點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為“馬攔過河卒”。

棋盤用座標表示,A點(0, 0)、B點(n, m)(n, m為不超過20的整數),同樣馬的位置座標是需要給出的。現在要求你計算出卒從A點能夠到達B點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。

輸入
一行四個資料,分別表示B點座標和馬的座標。(保證所有的資料有解)
輸出
一個數據,表示所有的路徑條數。
樣例輸入
6 6 3 3
樣例輸出
6

這題做的時候沒想到用DP,用的DFS超時了就沒管了。
補的題
在這裡插入圖片描述

根據此圖可以推得 a[i][j]=a[i][j-1]+a[i-1][j]

#include<iostream>
#include<algorithm>
using
namespace std; const int xx[9] = {0, -2, -1, 1, 2, 2, 1, -1, -2};//馬走日的9種狀態 const int yy[9] = {0, 1, 2, 2, 1, -1, -2, -2, -1}; int n,m,u,v; long long a[100][100],s[100][100]; int main(){ cin>>n>>m>>u>>v; n+=2;m+=2;u+=2;v+=2; //+2防止陣列越界 a[2][2] = 1; //初始位置為1 for(int
i = 0; i <= 8; i++) s[u+xx[i]][v+yy[i]] = 1; //馬可能的位置 for(int i=2; i<=n;++i){ for(int j=2;j<=m;++j){ if(s[i][j])continue; a[i][j]=max(a[i][j],a[i-1][j]+a[i][j-1]); } } cout<<a[n][m]; return 0; }

問題 B: 選數1

題目描述
已知 n 個整數 x1,x2,…,xn,以及一個整數 k(k<n)。從 n 個整數中任選 k 個整數相加,可分別得到一系列的和。例如當 n=4,k=3,4 個整數分別為 3,7,12,19 時,可得全部的組合與它們的和為:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34。
現在,要求你計算出和為素數共有多少種。
例如上例,只有一種的和為素數:3+7+19=29)。
輸入
鍵盤輸入,格式為:
n , k (1<=n<=20,k<n)
x1,x2,…,xn (1<=xi<=5000000)
輸出
螢幕輸出,格式為:
一個整數(滿足條件的種數)。
樣例輸入
4 3
3 7 12 19
樣例輸出
1

就是DFS模板,唯一難點可能是用過得不能重複出現比如 3 7 12 和 7 3 12是一次搜尋

# include<iostream>
# include<cmath>
# include<algorithm>
using namespace std;
int n,k,a[25],ans,b[25],vis[25],t;
long long s[1000000];
int isprime(int n){  
    for(int i=2;i<=sqrt(n);i++)
     if(n%i==0)  return 0;
    return 1;
}
void dfs(int res,int i){
     if(res==k) {  long long sum=0;
                    for(int i=0;i<k;i++)
                      sum+=b[i];
                    if(isprime(sum)) ans++;
                    return ;
                }
      for(int j=i;j<n;j++){
         if(!vis[j]){
                       b[res]=a[j];
                       vis[j]=1;
                       dfs(res+1,j);
                       vis[j]=0;
                    }
      }
      return ;
}
int main(){
     cin>>n>>k;
     for(int i=0;i<n;i++)
      cin>>a[i];
     dfs(0,0);
     cout<<ans;
     return 0;
}

問題 C: 產生數

題目描述
給出一個整數 n(n<1030) 和 k 個變換規則(k<=15)。
規則:
一位數可變換成另一個一位數:
規則的右部不能為零。
例如:n=234。有規則(k=2):
2-> 5
3-> 6
上面的整數 234 經過變換後可能產生出的整數為(包括原數):
234
534
264
564
共 4 種不同的產生數
問題:
給出一個整數 n 和 k 個規則。
求出:
經過任意次的變換(0次或多次),能產生出多少個不同整數。
僅要求輸出個數。
輸入
鍵盤輸人,格式為:
  n k
  x1 y1
  x2 y2
  … …
  xn yn
輸出
螢幕輸出,格式為:一個整數(滿足條件的個數)
樣例輸入
234 2
2 5
3 6
樣例輸出
4

對於每一位都進行搜尋。然後將結果累乘,每次變化肯定是不同得所以不用判斷重複。

#include<bits/stdc++.h>
typedef  __uint128_t lll
using namespace std;
char a[39],k,x[19],y[19];
bool b[99];
int l,t;
lll s;
void out(lll x){
    if(x>9)out(x/10);
    putchar(x%10+48);
}
void dfs(char c){  //將可變化得對應b陣列賦1
    if(b[c])return;
    b[c]=1; 
    for(int i=0;i<k;i++)
     if(x[i]==c)  dfs(y[i]);
}
int main(){
    scanf("%s%d",a,&k);
    for(int i=0;i<k;i++)
    cin>>x[i]>>y[i];
    s=1;
    for(int i=0;a[i];i++){
        t=0;
        dfs(a[i]);  //每一位都搜尋
        for(char i='0';i<='9';i++)
          t+=b[i],b[i]=0;  //累加變化
        s*=t;
    }
    out(s);
    return 0;
}

問題 D: 級數求和

題目描述
已知:Sn= 1+1/2+1/3+…+1/n。顯然對於任意一個整數K,當n足夠大的時候,Sn大於K。
現給出一個整數K(1<=k<=15),要求計算出一個最小的n;使得Sn>K。

輸入
鍵盤輸入 k
輸出
螢幕輸出 n

樣例輸入
1
樣例輸出
2

一開始居然把n設定為1-15……還錯了一次麻了。

# include<bits/stdc++.h>
using namespace std;
long long n,ans;
int i;
double s;
int main(){
  cin>>n;
  s=1;
  for( i=2;;i++){
     s+=1.0/i;
     if(s>n)  break;
      
  }
  cout<<i<<endl;
   return 0;
}

問題 E: 幸運數字

題目描述
今年聖誕節,小明收到了很多禮物,每個禮物上都有一個數字,表示對小明的祝福。可 是小明有自己的想法,對小明來說,4 或者 7 的倍數是幸運數字。 現在,小明想要知道所有數字中幸運數字之和是多少?請你幫幫小明!
輸入
第一行一個整數n,表示小明收到了n份聖誕禮物。第二行包含n個整數,第i個數a[i]表示第i份禮物上的數字。
輸出
輸出小明心目中的幸運數字之和。
樣例輸入
5
12 13 14 15 16
樣例輸出
42
提示
樣例解釋
小明的幸運數字必須是 4 或者 7 的倍數,這裡符合條件的:12+14+16=42
【資料範圍】
40%的資料,n<=100,0<a[i]<=100;
70%的資料,n<=1000,0<a[i]<=10000;
100%的資料,n<=10000,0<a[i]<=10000000。

# include<bits/stdc++.h>
using namespace std;
long long n,ans,x;
int i;
double s;
int main(){
  cin>>n;
   while(n--){
    cin>>x;
    if(x%4==0||x%7==0) ans+=x;
   }
   cout<<ans<<endl;
   return 0;
}

問題 F: 對撞

題目描述
小明發明瞭一個數字對撞機,兩個位數相同的整數可以進行碰撞。碰撞過程中,將兩個 整數的每一位進行比較,較小的那個數字會被撞得粉碎,較大的數字保留下來(如果兩數 相同,都會保留)。例如下面例子中:

兩個整數 13570 和 21673 碰撞後,對應數位上較小的值已經消失,碰撞的結果為:第一 個數字剩下 37,第二個數字剩下 2673。
現在小明想讓你寫一個程式來顯示數字碰撞機的結果,輸入兩個整數,輸出碰撞後的兩 個數字。(注意最終結果不能包含多餘的前導 0)

輸入
第一行一個整數 x,表示輸入的第一個整數。 第二行一個整數 y,表示輸入的第二個整數。
輸出
輸出包含兩行,第一個表示 x 碰撞後的結果。 第二行表示 y 碰撞後的結果。 若 x 或者 y 所有數位上的數字都消失了,該行輸出“BOOM”注意都是大寫的。
樣例輸入
【樣例1】
13570
21673
【樣例2】
300
500
【樣例3】
1234
5678
樣例輸出
【樣例1】
37
2673
【樣例2】
0
500
【樣例3】
BOOM
5678

簡單模擬題,慢慢寫都能AC,我一開始還在考慮兩個數字長度不等。。。

# include<bits/stdc++.h>
using namespace std;
char x[1005],y[1005];
int a[1005],b[1005],i,j,f;
 
int main(){
     cin>>x>>y;
     for(i=0;x[i];i++)
      if(x[i]>=y[i])  a[i]=x[i]-'0';  //大於等於得話就賦值
       else           a[i]=-1;        //否則該位置賦-1
 
     for( i=0;x[i];i++)    
      if(a[i]!=-1) break;           //只要不是-1就結束迴圈
     if(x[i]==0) f=1,cout<<"BOOM"<<endl;//如果當前X[i]=='\0'說明全是-1,固輸出BOOM
    if(f==0){   //若f的值還是0說明不 都是-1
     for(i=0;x[i];i++){
         if(a[i]!=0&&a[i]!=-1){ //第一個不是0或-1得數開始輸出後面所有(控制前導0)
                    for(j=i;x[j];j++) 
                     if(a[j]!=-1) cout<<a[j]; //只要當前不是-1就原樣輸出
                     printf("\n");
                     break;    //結束迴圈
                    }
     }
     if(x[i]==0) cout<<0<<endl; //如果x[i]=='\0'說明當前就是0
    }  
     //下一行與上面同理~~~
    int f=0;
     
      for(i=0;y[i];i++)
      if(y[i]>=x[i])  b[i]=y[i]-'0';
       else           b[i]=-1;
 
     for( i=0;y[i];i++)
      if(b[i]!=-1) break;
     if(y[i]==0) f=1,cout<<"BOOM"<<endl;
      
    if(f==0){
 
     for(i=0;y[i];i++){
         if(b[i]!=0&&b[i]!=-1){
                    for(j=i;y[j];j++)
                     if(b[j]!=-1) cout<<b[j];
                     printf("\n");
                     break;
                    }
     }
     if(x[i]==0) cout<<0<<endl;
    } 
     return 0;
}

問題 G: 差值求和

題目描述
小明最近學習了差的絕對值,|a-b|表示a-b的絕對值,若a-b>=0,則|a-b|=a-b;若a-b<0,則|a-b|=-(a-b)。
經過幾次練習,小明已經熟練掌握了差的絕對值,現在他找來了N個整數,開始任意取出兩個數,求差的絕對值,再將所有差的絕對值相加。例如N=4,有4個整數,分別是1,2,3,4。任取兩個數有6種取法,|1-2|=1,|1-3|=2,|1-4|=3,|2-3|=1,|2-4|=2,|3-4|=1,它們的和就是10。
由於運算量太大,累壞了小明。請你寫一個程式幫他計算一下吧。

輸入
第一行一個整數n,表示有n個整數
第二行n個整數,表示小明寫下的n個整數

輸出
輸出一個數,表示任意兩數差的絕對值之和。
樣例輸入 Copy
【樣例1】
3
3 1 2
【樣例2】
4
1 2 3 4
樣例輸出 Copy
【樣例1】
4
【樣例2】
10

錯誤做法➡暴力 ❌
正確做法➡排序找規律 √

我們拿 1 5 3 8 舉例

第一步我們先排序變成 1 3 5 8

第一個數的計算和為 5 - 1 + 8 - 1 + 3 - 1
第二個數的計算和為 5 - 3 + 8 - 3
第三個數的計算和為 8 - 5

這裡你有沒有發現一點規律?
第一個數和比第二個數和 多了 3-1(差)2個 額外的差(3-1)
第二個數和比第三個數和 多了 5-3(差)1個 額外的差(5-3)

所以我們好像推到了一個公式!!

1.如果後面一個數與前面一個不相等,

那麼第i個數的=第i-1額外的差

2.如果第i個數和第i-1個數相等,

那麼第i個數的和=第i-1

# include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005],n,sum,ans,t;
 
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);    
    sort(a+1,a+1+n);
     
    for(ll i=2;i<=n;i++)
      sum+=a[i]-a[1];
 
    t=sum;ans=sum;
    for(ll i=2;i<=n-1;i++)
    {
        if(a[i]!=a[i-1])       sum=t-(n-i)*(a[i]-a[i-1])-(a[i]-a[i-1]);
        else if(a[i]==a[i-1])  sum=t;
        t = sum;
        ans += sum;
    }
    cout<<ans;
    return 0;
}

問題 H: 取數遊戲

題目描述
小明正在玩一個取數遊戲,首先他有N個整數,從中任取出4個整數a,b,c,d(每個數只能取一次),若滿足a=b<c=d,則稱這樣的四個數(a,b,c,d)為勝利四元組,可以取得勝利。例如:共有4個數,分別為1,1,3,3;a取第1個,b取第2個,c取第3個,d取第4個數,那麼就可以滿足條件。注意,這裡a,b,c,d四個數是獨立取的,因此a取第2個,b取第1個,c取第3個,d取第4個也算作不同的方案。所以這樣4個數共有4種取法。
小明想要知道,有多少種取數方案,可以取出勝利四元組。方案數可能很多,小明只要知道結果除1000000007的餘數即可。

輸入
第一行一個整數N,表示小明共有N個整數。
第二行N個整數,第i個數a[i],表示第i個整數。

輸出
一個整數,表示滿足條件的四元組取法,最終結果對1000000007取模。
樣例輸入
4
3 1 3 1
樣例輸出
4

一開始以為這題就是找不重複個數然後/2*4,結果就得了9分,然後就不會寫了。。
待補……

問題 I: Children and Candies I

題目描述
There are N children in AtCoder Kindergarten. Mr. Evi will arrange the children in a line, then give 1 candy to the first child in the line, 2 candies to the second child, …, N candies to the N-th child. How many candies will be necessary in total?

Constraints
1≤N≤100
輸入
The input is given from Standard Input in the following format:
N
輸出
Print the necessary number of candies in total.
樣例輸入
3
樣例輸出
6
提示
The answer is 1+2+3=6.

# include<bits/stdc++.h>
using namespace std;
long long n,ans;
int main(){
  cin>>n;
  for(int i=1;i<=n;i++)
   ans+=i;
   cout<<ans<<endl; 
   return 0;
}

問題 J: Unhappy Hacking I

題目描述
Sig has built his own keyboard. Designed for ultimate simplicity, this keyboard only has 3 keys on it: the 0 key, the 1 key and the backspace key.
To begin with, he is using a plain text editor with this keyboard. This editor always displays one string (possibly empty). Just after the editor is launched, this string is empty. When each key on the keyboard is pressed, the following changes occur to the string:
The 0 key: a letter 0 will be inserted to the right of the string.
The 1 key: a letter 1 will be inserted to the right of the string.
The backspace key: if the string is empty, nothing happens. Otherwise, the rightmost letter of the string is deleted.
Sig has launched the editor, and pressed these keys several times. You are given a string s, which is a record of his keystrokes in order. In this string, the letter 0 stands for the 0 key, the letter 1 stands for the 1 key and the letter B stands for the backspace key. What string is displayed in the editor now?

Constraints
1≤|s|≤10 (|s| denotes the length of s)
s consists of the letters 0, 1 and B.
The correct answer is not an empty string.
輸入
The input is given from Standard Input in the following format:
s
輸出
Print the string displayed in the editor in the end.
樣例輸入
01B0
樣例輸出
00
提示
Each time the key is pressed, the string in the editor will change as follows: 0, 01, 0, 00.

開個大點得陣列,碰到0或者1就放進去;碰到B,並且當前下標大於0(這個判斷下標很重要,一開始漏了錯了)就下標自減。

# include<bits/stdc++.h>
using namespace std;
long long n,ans,x;
int i,j;
char a[100],b[100];
int main(){
  cin>>a;
  j=0;
  for(int i=0;a[i];i++){
    if(a[i]=='0'||a[i]=='1')    b[j++]=a[i];
    if(a[i]=='B'&&j>0)             j--;
  }
 
   for(int i=0;i<j;i++)
    cout<<b[i];
   return 0;
}

問題 K: Be Together

題目描述
Evi has N integers a1,a2,…,aN. His objective is to have N equal integers by transforming some of them.
He may transform each integer at most once. Transforming an integer x into another integer y costs him (x−y)2 dollars. Even if ai=aj(i≠j), he has to pay the cost separately for transforming each of them.
Find the minimum total cost to achieve his objective.

Constraints
1≤N≤100
−100≤ai≤100
輸入
The input is given from Standard Input in the following format:

N
a1 a2 … aN
輸出
Print the minimum total cost to achieve Evi’s objective.
樣例輸入
2
4 8
樣例輸出
8
提示
Transforming the both into 6s will cost (4−6)2+(8−6)2=8 dollars, which is the minimum.

找到最小值和最大值,然後在這個範圍內列舉就行了。

# include<iostream>
# include<algorithm>
# include<cmath>
using namespace std;
 
int n,a[105],maxn,ans,res,minn;
 
int main(){
     cin>>n;
     minn=0x3ffff;
     for(int i=1;i<=n;i++)
      {
        cin>>a[i];
        maxn=max(maxn,a[i]);
        minn=min(minn,a[i]);
      }
      ans=999999999;
     for(int i=minn;i<=maxn;i++){
         res=0;
         for(int j=1;j<=n;j++)
          res+=pow(a[j]-i,2);
         
        ans=min(ans,res);
     }
     cout<<ans<<endl;
     return 0;
}

問題 L: Children and Candies II

題目描述
12:17 (UTC): The sample input 1 and 2 were swapped. The error is now fixed. We are very sorry for your inconvenience.
There are N children in AtCoder Kindergarten, conveniently numbered 1 through N. Mr. Evi will distribute C indistinguishable candies to the children.
If child i is given a candies, the child’s happiness will become xia, where xi is the child’s excitement level. The activity level of the kindergarten is the product of the happiness of all the N children.
For each possible way to distribute C candies to the children by giving zero or more candies to each child, calculate the activity level of the kindergarten. Then, calculate the sum over all possible way to distribute C candies. This sum can be seen as a function of the children’s excitement levels x1,…,xN, thus we call it f(x1,…,xN).
You are given integers Ai,Bi(1≤i≤N). Find modulo 109+7.

Constraints
1≤N≤400
1≤C≤400
1≤Ai≤Bi≤400(1≤i≤N)
Partial Score
400 points will be awarded for passing the test set satisfying Ai=Bi(1≤i≤N).
輸入
The input is given from Standard Input in the following format:

N C
A1 A2 … AN
B1 B2 … BN
輸出
Print the value of modulo 109+7.
樣例輸入
2 3
1 1
1 1
樣例輸出
4

不會…………待補

問題 M: Unhappy Hacking II

題目描述
Sig has built his own keyboard. Designed for ultimate simplicity, this keyboard only has 3 keys on it: the 0 key, the 1 key and the backspace key.
To begin with, he is using a plain text editor with this keyboard. This editor always displays one string (possibly empty). Just after the editor is launched, this string is empty. When each key on the keyboard is pressed, the following changes occur to the string:
The 0 key: a letter 0 will be inserted to the right of the string.
The 1 key: a letter 1 will be inserted to the right of the string.
The backspace key: if the string is empty, nothing happens. Otherwise, the rightmost letter of the string is deleted.
Sig has launched the editor, and pressed these keys N times in total. As a result, the editor displays a string s. Find the number of such ways to press the keys, modulo 109+7.

Constraints
1≤N≤5000
1≤|s|≤N
s consists of the letters 0 and 1.
Partial Score
400 points will be awarded for passing the test set satisfying 1≤N≤300.

輸入
The input is given from Standard Input in the following format:
N
s
輸出
Print the number of the ways to press the keys N times in total such that the editor displays the string s in the end, modulo 109+7.
樣例輸入
3
0
樣例輸出
5
提示
We will denote the backspace key by B. The following 5 ways to press the keys will cause the editor to display the string 0 in the end: 00B, 01B, 0B0, 1B0, BB0. In the last way, nothing will happen when the backspace key is pressed.

又不會…………待補