owned this note
owned this note
Published
Linked with GitHub
ITSA線上程式競賽題目-中文題庫
=======================
## 2048
```cpp=
#include<iostream>
#include<sstream>
using namespace std;
int main(){
char v;
while(cin>>v){
cin.ignore(1,'\n');
string s;
long a[4][4];
for(int i=0;i<4;i++)
{
getline(cin,s);
istringstream ss(s);
string cut;
for(int j=0;j<4;j++){
getline(ss,cut,' ');
istringstream cc(cut);
cc>>a[i][j];
}
}
if(v=='U')
{for(int j=0;j<4;j++){
for(int k=0;k<4;k++){
for(int i=k+1;i<4;i++){
if(a[k][j]!=0&&a[i][j]!=0&&a[k][j]==a[i][j]){
a[k][j]+=a[i][j];
a[i][j]=0;
break;
}
else if(a[k][j]!=0&&a[i][j]!=0&&a[k][j]!=a[i][j]){break;}
for(int i=k+1;i<4;i++){
if(a[k][j]==0&&a[i][j]!=0){
a[k][j]+=a[i][j];
a[i][j]=0;
break;
}}
}
}
}}
else if(v=='D')
{for(int j=0;j<4;j++){
for(int k=3;k>0;k--){
for(int i=k-1;i>=0;i--){
if(a[k][j]!=0&&a[i][j]!=0&&a[k][j]==a[i][j]){
a[k][j]+=a[i][j];
a[i][j]=0;
break;
}
else if(a[k][j]!=0&&a[i][j]!=0&&a[k][j]!=a[i][j]){break;}
for(int i=k-1;i>=0;i--){
if(a[k][j]==0&&a[i][j]!=0){
a[k][j]+=a[i][j];
a[i][j]=0;
break;
}}
}
}
}}
else if(v=='L')
{for(int j=0;j<4;j++){
for(int k=0;k<4;k++){
for(int i=k+1;i<4;i++){
if(a[j][k]!=0&&a[j][i]!=0&&a[j][k]==a[j][i]){
a[j][k]+=a[j][i];
a[j][i]=0;
break;
}
else if(a[j][k]!=0&&a[j][i]!=0&&a[j][k]!=a[j][i]){break;}
for(int i=k+1;i<4;i++){
if(a[j][k]==0&&a[j][i]!=0){
a[j][k]+=a[j][i];
a[j][i]=0;
break;
}}
}
}
}}
else if(v=='R')
{for(int j=0;j<4;j++){
for(int k=3;k>0;k--){
for(int i=k-1;i>=0;i--){
if(a[j][k]!=0&&a[j][i]!=0&&a[j][k]==a[j][i]){
a[j][k]+=a[j][i];
a[j][i]=0;
break;
}
else if(a[j][k]!=0&&a[j][i]!=0&&a[j][k]!=a[j][i]){break;}
for(int i=k-1;i>=0;i--){
if(a[j][k]==0&&a[j][i]!=0){
a[j][k]+=a[j][i];
a[j][i]=0;
break;
}}
}
}
}}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(j==3){cout<<a[i][j];}
else{cout<<a[i][j]<<" ";}
}cout<<endl;
}
}
return 0;
}
```
## 迷宮問題
```cpp=
//右下角為出發點 (8,8) ,左上角為出口 (1,1)
//右 > 上 > 左 > 下
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
void p(vector<vector<string> >& map) //印出二維向量
{
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
if(j<9)cout<<map[i][j]<<" "; //要留意為什麼是 j,易錯點
else cout<<map[i][j]<<endl;
}
}
}
bool dfs( vector<vector<string> >& map,int sr/*上下*/,int sc/*左右*/)
{//右下角為出發點 (8,8) ,左上角為出口 (1,1)
if( sr > 0 && sc > 0 && sr < 9 && sc < 9 )//是否超界
{
if( map[sr][sc] == "0" ){//是否為未探索路徑
map[sr][sc] = "G";//預設為正確路徑
if( dfs( map, sr, sc+1 ) ){//右
return true;
}
else if( dfs( map, sr-1, sc ) ){//上
return true;
}
else if( dfs( map, sr, sc-1 ) ){//左
return true;
}
else if( dfs( map, sr+1, sc ) ){//下
return true;
}
else{
if( sr == 1 && sc == 1 ){//若為終點則改成 X ,且回傳正確
map[sr][sc] = "X";
return true;
}
else{//否則回傳錯誤並標記為錯誤路徑
map[sr][sc] = "D";
return false;
}
}
}
else return false;//若為已探索則回傳錯誤
}
else return false;//超界回傳錯誤
}
int main()
{
string s;
vector<vector<string> > map;
for(int i=0;i<10;i++) //讀入二維向量
{
getline(cin,s);
vector<string> tmp; //宣告內部向量 tmp
istringstream chs(s); //轉換為可分割字串型態
for(int j=0;j<10;j++)
{
string cs; //宣告被切割的字串 cs
getline(chs,cs,' '); //以空白做切割
tmp.push_back(cs); //存入內部向量 tmp
}
map.push_back(tmp); //再推入外部向量 map
}
dfs(map,8,8);
if( map[1][1] != "X" ){//若終點未被修改則表示未找到
map[1][1] = "X";//標記終點
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
map[8][8] = "S";//標記起點
p(map); //印出二維向量
return 0;
}
```
## C++陣列除法
```cpp=
#include<iostream>
#include<vector>
using namespace std;
int main(){
string str;//讀入字串暫存,
vector<int> a;//被除數
vector<int> b;//除數
bool aORb=true;//判定字串往何處儲存
for(int i=0;i<2;i++)
{
getline(cin,str);//讀入字串
for(int j=0;j<str.size();j++)//與該字串的每個字
{
int changeNum=int(str[j]-'0');//轉成數字
if(aORb==false)//判定是否為除數的字串
{
b.push_back(changeNum);//推入除數字串
}
else
{
a.push_back(changeNum);//推入被除數字串
}
}
aORb=false;//改變下一個字串的儲存區
}
//--------------輸入--------------
vector<int> re;//商
int deltaLen=a.size()-b.size()+1;//計算次數(商數的長度)
int buf[b.size()]={0};//除數計算區初始化
int *ap=&a[0];// 當前計算位置指標
for(int i=0;i<deltaLen;i++)//尋找商數
{
for(int j=0;j<9;j++)//尋找該次商數
{
bool r=false;//判定是否為商數
for(int k=0;k<b.size();k++)//比較大小
{
if(buf[k]<*(ap+k)){break;}//找到任意較小的位數就淘汰
else if(buf[k]>*(ap+k)){r=true;break;}//否則就"錄取"
}
if(r==true)//若為商數,則輸出商數結果
{
re.push_back(j-1);//推入商數結果
for(int m=0;m<b.size();m++)//計算區減一次
{
buf[m]-=b[m];
if(buf[m]<0){buf[m-1]--;buf[m]+=10;}//進位
}
break;//跳出迴圈
}
for(int m=0;m<b.size();m++)//計算區加一次
{
buf[m]+=b[m];
if(buf[m]>10){buf[m-1]++;buf[m]-=10;}//進位
}
}
//--------------找到該次商數--------------
for(int j=0;j<b.size();j++)//與被除數做計算
{
*ap=*ap-buf[j];//減法
if(*ap<0)//進位
{
*(ap-1)-=1;
*ap+=10;
}
ap++;//指標右移
}
ap=ap-(b.size()-1);//指標位置來到下一次計算起始位置
for(int j=0;j<b.size();j++){buf[j]=0;}//計算區歸0
//--------------與被除數計算完畢--------------
}
cout<<"商數為:";
for(int i=0;i<re.size();i++){cout<<re[i];}cout<<endl;
int z=0;//判定首個非0數
b.clear();//淨空再利用,儲存餘數
for(int i=0;i<a.size();i++)//過濾出餘數
{
if(a[i]!=0&&z==0){b.push_back(a[i]);z++;}//遇到首個非0
else if(z!=0){b.push_back(a[i]);}//之後一律推入
}
cout<<"餘數為:";
for(int i=0;i<b.size();i++){cout<<b[i];}cout<<endl;
return 0;
}
```
# 泛洪演算法範例題 --- ITSA- Arrayc 151~200-[C_AR154-易]感染被包圍的人
題目連結:https://e-tutor.itsa.org.tw/eTutor/mod/programming/view.php?id=24871
作法:
```cpp=
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
void p(vector<vector<string> >& map) //印出二維向量
{
for(int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if(j<6)cout<<map[i][j]<<" ";
//要留意為什麼是 j,易錯點
else cout<<map[i][j]<<endl;
}
}
}
//銜接下面演算法任一種寫法
```
## 泛洪演算法(一)
```cpp=
//泛洪演算法(一)
void floodfill(vector<vector<string> >& map,int sr,int sc)
{
if(sr >= 0 && sc >= 0 && sr < 7 && sc < 7 && map[sr][sc] == "0")
{ //若沒超出邊界且等於 0
map[sr][sc] = "2"; //將確定生存的目標做標記為2
floodfill(map,sr+1,sc); //上
//floodfill(map,sr+1,sc+1); //右上
floodfill(map,sr,sc+1); //右
//floodfill(map,sr-1,sc+1); //右下
floodfill(map,sr-1,sc); //下
//floodfill(map,sr-1,sc-1); //左下
floodfill(map,sr,sc-1); //左
//floodfill(map,sr+1,sc-1); //左上
}
}
```
## 泛洪演算法(二)
```cpp=
//泛洪演算法(二)
void floodfill(vector<vector<char> >& map, int x, int y)
{
if (x >= 7 || y >= 7 || x < 0 || y < 0)
return;
if (map[x][y] == '0')
{
map[x][y] = '2';
floodfill(map, x - 1, y); //下
//floodfill(map, x - 1, y - 1);//左下
floodfill(map, x, y - 1); //左
//floodfill(map, x + 1, y - 1);//左上
floodfill(map, x + 1, y); //上
//floodfill(map, x + 1, y + 1);//右上
floodfill(map, x, y + 1); //右
//floodfill(map, x - 1, y + 1);//右下
}
if(map[x][y] == 'X' || map[x][y] == '2')
return;
}
```
---銜接前面---
```cpp=
void change(vector<vector<string> >& map,string s,string cs)
{ //將整個二維向量符合 s 的字串替換成字串 cs
for(int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if(map[i][j]==s)map[i][j]=cs;
}
}
}
int main()
{
string s;
vector<vector<string> > map;
for(int i=0;i<7;i++) //讀入二維向量
{
getline(cin,s);
vector<string> tmp; //宣告內部向量 tmp
istringstream chs(s); //轉換為可分割字串型態
for(int j=0;j<7;j++)
{
string cs; //宣告被切割的字串 cs
getline(chs,cs,' '); //以空白做切割
tmp.push_back(cs); //存入內部向量 tmp
}
map.push_back(tmp); //再推入外部向量 map
}
//僅檢測最外圈是否有 0
//上面的邊
for(int i=0;i<7;i++){if(map[0][i]=="0")floodfill(map,0,i);}
//右邊
for(int i=0;i<7;i++){if(map[i][6]=="0")floodfill(map,i,6);}
//最下排
for(int i=0;i<7;i++){if(map[6][i]=="0")floodfill(map,6,i);}
//最左邊
for(int i=0;i<7;i++){if(map[i][0]=="0")floodfill(map,i,0);}
change(map,"0","I"); //將剩餘的 0,即被感染的替換成 I
change(map,"2","0"); //將標記的 2,替換成 0
p(map); //印出二維向量
return 0;
}
//泛洪演算法範例題 結束
```