2017年3月23日 星期四

Y7M3 P2A 練習-7 俄羅斯方塊

100北二區資訊複賽

1.圈叉連線數問題(zj:a817)      ✔(上次已傳)

2.藏寶問題(zj:a824)                ✔(上次已傳)

3.小四數學(zj:a825)                ✔(上次已傳)

4.天氣預測問題(zj:a826)          ✔(上次已傳)

5.俄羅斯方塊問題(zj:a827)

101北二區資訊複賽

1.解碼問題(zj:a818)                  ✔(上次已傳)

2.小三資優數學(zj:a819)            

3.小精靈吃數字(zj:a820)            ✔(上次已傳)

4.王者之路(zj:a821)                   ✔(上次已傳)

5.滾球遊戲(zj:a822)                   ✔(上次已傳)

100年5.俄羅斯方塊問題(zj:a827)  ================ 
// a827. 5.俄羅斯方塊問題 -- 100學年度桃竹苗區資訊學科能力競賽

#include <iostream>
#include <cstring>
#include <set>
using namespace std;

const int BitN = 8;   // 牆寬 8 格
const int BoxN = 11;  // 11 種 (含旋轉)的方塊
int box[BoxN][2]={{3,3}, {0,15}, {1,1}, {3,1}, {3,6}, {3,2}, {6,3}, {2,7}, {7,2}, {3,2}, {3,1} };  // 每種2列
int bw[BoxN] = { 2, 4, 1, 2, 3, 2, 3, 3, 3, 2, 2};  // 11種 方塊的 寬度
int ty[BoxN] = {1, 2,2,  3,3,  4,4,  5,5,5,5 }; //屬於哪一種類型
int w[2];  // 牆 2列
set<int> out;
set<int>::iterator it;

int chk(int bi )
{
int i,b0,b1, sco, tot=0;
for(i=BitN-bw[bi]; i>=0; --i)
{
b1 = box[bi][1]<<i ; // 小方塊的下方列 由左至右的值 
if( b1&w[0] ) continue; // bit and 值非 0 即無法放入第1層
// 進入第1層,接著檢查是否可進入第2層
b0 = box[bi][0]<<i ; // 小方塊的上方列 由左至右的值
if( (b0&w[0]) == 0 && (b1&w[1]) == 0 ) // 2層皆進入 , 因運算序(bit and)需括住
{
sco = ( ((b0|w[0])==255) + ((b1|w[1])==255) ) * 8;  // 因運算序(bit or)需括住
} else { // 只能進一層,算第1層的分數
sco = ( (b1|w[0]) == 255 ) * 8;
}
if( sco>tot ) tot=sco;
}
return tot;
}

int main(void)
{
int i,j;

string s;
// 讀入兩列 牆
for(i=0; i<2; ++i) // 2列
{
cin >> s;
w[i] = 0;
for(j=0; j<BitN; ++j)
 w[i] = w[i]*2 + (s[j]=='*');
}
int mx=0 , sco;
   for( i=0; i<BoxN; ++i) // 以 11種 方塊各求 可得的分數,最高的 放入 out
   {
    sco = chk(i);
    if( sco==0 || sco<mx ) continue;
    if( sco>mx ) out.clear();
    mx=sco;
    out.insert( ty[i] );  // 若分數 >= mx 加入 out , 數字同 set只有1個
   }
   if( mx == 0 ) cout << "0\n0\n";  // 印2列 0
   else { //最少一個
      it = out.begin();
    cout << (*it) ;
    for(++it; it!=out.end(); ++it)
     cout << ' ' << (*it) ;
    cout << endl << mx << endl;
   }
return 0;
}

/*  ----範例輸入
例一 :
000*0000
****0***
例二 :
***0****
***0****
-----------範例輸出
例一 :
2 4 5
8
例二 :
2
16
*/

2017年3月20日 星期一

Y7M3 P2A 練習-6 小三資優數學

100北二區資訊複賽

1.圈叉連線數問題(zj:a817)      ✔(上次已傳)

2.藏寶問題(zj:a824)                ✔(上次已傳)

3.小四數學(zj:a825)                ✔(上次已傳)

4.天氣預測問題(zj:a826)          ✔(上次已傳)

5.俄羅斯方塊問題(zj:a827)

101北二區資訊複賽

1.解碼問題(zj:a818)                  ✔(上次已傳)

2.小三資優數學(zj:a819)            

3.小精靈吃數字(zj:a820)            ✔(上次已傳)

4.王者之路(zj:a821)                   ✔(上次已傳)

5.滾球遊戲(zj:a822)                   ✔(上次已傳)

101年2.小三資優數學(zj:a819)  ================ 
// a819. 2.小三資優數學 -- 101學年度桃竹苗區資訊學科能力競賽
/*
a819 小三數學,三個數字三列,第1列:n{2~10}代表位數,第2列:k{n位的數字},第3列:可算出的結果 m
     n位數k的每位數之間可加運算符號使結果等於 m ,最多可加兩個符號{符號為 + , - , * , / 四種}兩個符號可相同 
     ===*** 題目中未說明,但若 先÷再*,暫時規定需能整除才加除號;例如  12/8*6不可以,不接受右列結果 {1.5*6=9、1*6=6}
*/

#include <iostream>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
int n,m ; //, cnt;
string s;
LL a,b,c;

LL cal(LL x, LL y , char op)  // 算出 x (op) y : op是+-*/
{
switch(op)
{
case '+': //+
 return x+y; break;
case '-': //-
 return x-y; break;
case '*': //*
 return x*y; break;
case '/': // ÷  y<>0且x÷y需整除,否則傳回 INF(不成立)
 if(y && x%y==0) return x/y; else return INF;
 break;
}
}
char ops[]={'-','+','*','/'};
void cut2(int p) // 將讀入的 數字串 s,切成左右兩部份:加1個符號在 索引 p之前
{                // 即 s[0~p-1] 一段轉成數值 a、 s[p~n-1] 一段 轉成數值 b
int i;
for(a=0, i=0; i<p; ++i) a=a*10+s[i]-'0';
for(b=0, i=p; i<n; ++i) b=b*10+s[i]-'0';
for(int op=0; op<4; ++op)
{
LL r = cal(a,b,ops[op]);
// cout << a <<ops[op] <<b <<'=' << r << endl;  //
if(r!=m) continue;
cout << a << ops[op] <<b << endl;
// ++cnt;
}
}

void cut3(int p, int q) // 將讀入的 數字串 s,切成三部份:加2個符號 {索引 p之前,索引 q之前}
{            // 即 s[0~p-1] 一段轉成數值 a、 s[p~q-1] 一段 轉成數值 b  s[q~n-1] 一段 轉成數值 c
int i,op1,op2;
for(a=0, i=0; i<p; ++i) a=a*10+s[i]-'0';
for(b=0, i=p; i<q; ++i) b=b*10+s[i]-'0';
for(c=0, i=q; i<n; ++i) c=c*10+s[i]-'0';
// cout << a <<','<<b<<','<<c<<endl;    //
//// === *** 運算式的優先序,先乘除後加減,應可建一個表以簡化程式碼,但我懶得再改了
for( op2=0; op2<4; ++op2)  // r2 = b { + -  * / } c 先 , 再 a{+-}r2 除了  - + 或 - -
{
LL r2 = cal(b,c,ops[op2]);
// cout << a <<ops[op] <<b <<'=' << r << endl;  //
if(r2 == INF) continue;
for( op1=0;op1<2; ++op1)
{
if(op1==0 && op2<2) continue;
LL r1 = cal(a,r2,ops[op1]);
//   cout << a << ops[op1] <<b << ops[op2] <<c <<'=' << r1 << endl;  //
if(r1 !=m ) continue;
  cout << a << ops[op1] <<b << ops[op2] <<c << endl;
//   ++cnt;
}
}
LL r = cal( cal(a,b,'-') , c , '+' );  // a-b+c
// cout << a << '-' <<b << '+' <<c  <<'=' << r << endl;  //
if (r==m) {  cout << a << '-' <<b << '+' <<c << endl;  } //  ++cnt;
r = cal( cal(a,b,'-') , c , '-' );  // a-b-c
// cout << a << '-' <<b << '-' <<c  <<'=' << r << endl;  //
if (r==m) { cout << a << '-' <<b << '-' <<c << endl;  } //  ++cnt;

for( op1=2; op1<4; ++op1)  // r1 = a{ * / } b 先 , 再 r1{+-*/} c ,除了 a/b*c
{
LL r1 = cal(a,b,ops[op1]);
// cout << a <<ops[op] <<b <<'=' << r << endl;  //
if(r1 == INF) continue;
for( op2=0;op2<4; ++op2) // 除了 a/b*c 先算 a*c/b
{
if(op1==3 && op2==2) continue;
LL r2 = cal(r1,c,ops[op2]);
//   cout << a << ops[op1] <<b << ops[op2] <<c <<'=' << r2 << endl;  //
if(r2 !=m ) continue;
cout << a << ops[op1] <<b << ops[op2] <<c << endl;
// ++cnt;
}
}
r = cal( cal(a,c,'*') , b , '/' );  // a/b*c => a*c/b ,例 9/6*4 = 6
// cout << a << '/' <<b << '*' <<c <<'=' << r<< endl;     //
if (r!=m) return;
cout << a << '/' <<b << '*' <<c << endl;
// ++cnt;
}

int main(void)
{
int i,j;
cin >> n >> s >> m;
// {
LL k=0;
for(i=0; i<n; ++i) k=k*10+s[i]-'0';
if(k==m) { 
 cout << s << endl;
 return 0;
}
  // cnt =0;
for(i=1; i<n; ++i)  //切成 2 部份,切點位置 p:1~n-1
cut2(i);
for(i=1;i<n-1;++i)
 for(j=i+1; j<n; ++j)  //切成 3 部份,切點位置 p:1~n-2 , q:p+1~n-1
   cut3(i,j);
// if(cnt==0) cout << s<<','<<m<<endl;
// }

return 0;
}
/*

*/


/*  ----範例輸入
例一 : 12/3 = 4
3
123
4
例二 : 2+3*4 = 14
3
234
14
例三 : 240/15 = 16
5
24015
16
例四 : 8-6+2
3
862
4
例五 9/6*4 <<此例應不成立
3
964
6
例六  1357-924*680
10 
1357924680 
-626963
-----------範例輸出
12/3
2+3*4
240/15
8-6+2
9/6*4
1357-924*680

*/

Z2AY7M3 練習-4 (17題題單及參考)

4/10(一)測驗題單 (題目名加上連結的表示範例完成)
假設由文字方塊輸入,呼叫 Function MyPxx( S As String ) As String後傳回要輸出的字串
以下只有M5P11附主程式部份,其餘類似

105模擬
M5P11
105模擬
M5P22
105模擬
M5P42
105正式
F5P11
字串問題:計算字數
105正式
F5P12
字串問題:摩斯電碼
105正式
F5P21
數學問題:網段ID
105正式
F5P22
數學問題:最大公約數計算
104模擬
M4P12
數學問題:N!尾數的0
104模擬
M4P21
其他:計程車費率計算
104模擬
M4P42
其他:數字反轉後相加
104正式
F4P11
生活問題:電梯電費計算系統
104正式
F4P22
數學問題:最大公約數計算
104正式
F4P31
其他:計算位元為1的個數
103模擬
M3P11
數學問題:判斷是否為質數
103模擬
M3P12
數學問題:解二元一次聯立方程式之根
103模擬
M3P21
103模擬
M3P22
編碼處理:凱撒密碼

======  105模擬 M5P11 數學問題:質數
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim s As String = TextBox1.Text
        Label1.Text = M5P11(s)
    End Sub
    Function M5P11(ByVal s As String) As String
        '傳入一個 字串s 轉為整數 x ,判斷是否為質數,是傳回字串T,否傳回F
        Dim x As Integer = s
        If x < 2 Then Return "F"
        For k = 2 To Math.Sqrt(x)
            If x Mod k = 0 Then Return "F"
        Next
        Return "T"
    End Function
=====輸入範例
1
2
3
4
5

6
7
8

=====輸出範例
F
T
T
F
T

F
T
F
===============

======   ' 105模擬 P22:行、字數、字元數

      Function M5P22(ByVal s As String) As String
        '原檔案輸入 傳入一個整數 fn 為要讀入的 檔案編號
      '改為由文字方塊讀入
        Dim a, b, c As Integer
        Dim line() = s.Split(vbCrLf)
        a = line.Length
        For i = 0 To UBound(line)
            c += line(i).Length
            Dim dat() = line(i).Split(" ")
            b += dat.Length
        Next
        ' 由 multiline的文字方塊讀入 每列有 Enter會多1字,除了最後一列不按 Enter
        c -= (a - 1)
        Return a & "," & b & "," & c
=====輸入範例
a
b
c
cd

=====輸出範例
4,4,5
===============

======  105模擬 M5P42 十進制數轉成二進制數
     Function M5P42(ByVal s As String) As String
        Dim dat() = s.Split(",")
        Dim a As Integer = StrReverse(dat(0))
        Dim b As Integer = StrReverse(dat(1))
        Dim sum As Integer = StrReverse((a + b) & "")
        Return d2b(sum)   ' 呼叫自訂函式d2b將十進位轉二進位
    End Function

    Function d2b(ByVal sum As Integer) As String
     '將傳入的十進位數值 sum 傳為二進位後傳回 字串
        d2b = ""
        If sum = 0 Then Return "0"
        Do Until sum = 0
            d2b = sum Mod 2 & d2b
            sum \= 2
        Loop
    End Function


=====輸入範例
1,13
123,14

172,93
100,2
=====輸出範例
10111
100000111

1101
11
===============

 ======  103模擬 M3P21 編碼處理:摩斯電碼

 REM tbl陣列: 第1列 A~G  , 第2列 H~M  , 第3列 N~T  , 第4列 U~Z 
    Dim tbl() = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.",
               "....", "..", ".---", "-.-", ".-..", "--",
               "-.", "---", ".--.", "--.-", ".-.", "...", "-",
              "..-", "...-", ".--", "-..-", "-.--", "--.."}
    Function M3P21(ByVal s As String) As String
        Dim ans As String = ""
        Dim d() = s.Split(" ")
        For j = 0 To UBound(d)
            Dim k = Array.IndexOf(tbl, d(j))  '由tbl找 符合d(j) 的字串,傳回索引
            ans &= Chr(k + 65)  '索引為 0A,1B,...,24Y,25Z : 加上65即為 65~90
        Next
        Return ans
    End Function
=====輸入範例
... --- ...

-.-- --- ..-

.- -. -..

..

.... . .-.. .--.

.--. .-. --- --. .-. .- --

...- .. .-. - ..- .- .-.. -... .- ... .. -.-.

--. --- --- --. .-.. .

=====輸出範例
SOS
YOU
AND
I
HELP
PROGRAM
VIRTUALBASIC
GOOGLE
===============