先說廢話,當時做了但是沒有ac,問題是乙個測試用例也沒過直接掛蛋,非常不爽的同時一直懷疑應該是在輸入輸出踩坑,邏輯上嘛...昨天重新把題目挖出來做了一下,都是暴力解法,效率估計不高。
注:下面所有解法都只能通過測試用例,因為無法在hihocoder上提交了,所以不保證正確,真心求測試資料
題目1 :
電子數字
時間限制
:10000ms
單點時限
:1000ms
記憶體限制
:256mb 描述
電子數字在生活中很常見,而許多的電子數字是由
led數碼管製作而成。數字
led數碼管一般由
7個發光二極體封裝在一起,組成
'8'字型,引線在內部連線完成。如下圖所示,我們可以對每個發光管進行編碼從1到
7。而數字
0到數字
9可以由這七根發光管的亮暗來表示。
led數碼管的二極體進行編碼
用led
數碼管表示數字
0-9假設我們現在有從左到右排列好的k個
led數碼管,並且我們已知每個數碼管當前有哪些編號的二極體是亮著的,另外剩餘的二極體由於某些原因,我們並不清楚它們的亮暗情況。由於已經有部分二極體是確定亮著的,所以每個
led數碼管能表示的數字範圍會有所縮小,譬如假設
1號二極體已經確定是亮著的狀態,那麼這個
led數碼管就不能表示數字1和
4。我們想知道的是,給定乙個數
n,在這k個
led數碼管的當前亮暗的狀態下,所有可能表示的數中,比
n小的數有多少個。
注意,前導
0是必須的,假設有
4個數碼管的話,
'0000'表示0
,'0123'
表示123
,即每個數的表示方法唯一。 輸入
每個輸入資料報含多個測試點。
第一行為測試點的個數
s ≤ 100
。之後是
s個測試點的資料。測試點之間無空行。
每個測試點的第一行為
k(1 ≤ k ≤ 5)和n
(0 ≤ n ≤ 109)
。之後是
k行,每行表示對應數碼管已點亮的二極體的情況。每行至少包含乙個數字,表示對應點亮的二極體的編號,即每個數碼管至少有一根二極體是點亮的。二極體編號的範圍保證在1到
7之間,且每行無重複編號。
注意表示數碼管點亮情況的每行數字之間以及行首行末之間可能存在冗餘空格,每行的字元總長度不超過
100。 輸出
對於每個測試點,對應的結果輸出一行,表示這
k個數碼管在當前狀態下,所有可能表示的數中,比
n小的數有多少個。
樣例解釋
第乙個樣例中,只有
'020', '026', '028'
符合要求。
第三個樣例中,只有
'000'
符合要求。
樣例輸入3
3 50
3 1
1 4 5
1 5 6 7
4 100
1 2 3
4 5 6
7 1 1 7
樣例輸出3
0 1
解法的話在**中都有注釋,應該比較好懂:1)判斷每一行可能出現的數字2)數字組合3)比較統計結果。
#include #include #include using namespace std;
// 每個二極體對應數字
const int pipe_status[10] = ,
, ,, , ,
};// 每個二極體對應的數字的個數
const int pipe_lens[7] = ;
// 求二極體對應的數字的交集,複雜度為 o(min(len1, len2))
void picknum(vector& res, const int* b, int blen)
} // 將臨時變數的資料複製到res,更新當前交集res
res.clear();
for (i = 0; i < tmp.size(); ++i)
res.push_back(tmp[i]);
}// 求各個位上的陣列組合
void combinenum(vector& res, vector& num)
int main()
// 否則求當前交集與新的二極體對應的數字的交集,更新交集
else }}
} vectorres;
// 用最高位的數字初始化res
for (int i = 0; i < nums[0].size(); ++i)
res.push_back(nums[0][i]);
// 計算數字組合
for (int i = 1; i < k; ++i)
// 統計結果
for (int i = 0; i < res.size(); ++i)
if (res[i] < n)
count++;
cout << count << endl;
}}
稍微修改過一點的做法是,如果n的數量級比k行小,那麼其實在前(k-base)行就可以不做計算直接忽略,因為一定不比n小。其中base指n的基數
#include #include #include using namespace std;
// 每個二極體對應數字
const char pipe_status[10] = ,
, ,, , ,
};// 每個二極體對應的數字的個數
const int pipe_lens[7] = ;
// 求二極體對應的數字的交集,複雜度為 o(min(len1, len2))
void picknum(vector& res, const char* b, int blen)
} // 將臨時變數的資料複製到res,更新當前交集res
res.clear();
for (i = 0; i < tmp.size(); ++i)
res.push_back(tmp[i]);
}// 求各個位上的陣列組合
void combinenum(vector& res, vector& num)
// 求n的基數
int getbaseofn(int n)
return base;
}int main()
for (int i = begin; i < k; i++)
// 否則求當前交集與新的二極體對應的數字的交集,更新交集
else }}
} vectorres;
// 用有效最高位的數字初始化res
for (int i = 0; i < nums[begin].size(); ++i)
res.push_back(nums[begin][i] - '0');
// 計算數字組合
for (int i = begin + 1; i < k; ++i)
// 統計結果
for (int i = 0; i < res.size(); ++i)
if (res[i] < n)
count++;
cout << count << endl;
}}
#include#include #include using namespace std;
int s, k, n, ans;
bool led[10][10];
bool oled[10][8] = ,,,
,,,,
,,};void dfs(int i, int tmp)
else if(i> s;
while(s--)
else}}
dfs(0, 0);
cout << ans << endl;
}return 0;
}
暑假訓練第一場C
題目 小的時候大家一定玩過 井 字棋吧。也就是在九宮格中,只要任意行 列,或者任意連續對角線上面出現三個相同的,就能獲勝。現在小明和小花也在玩三子棋,但是他們不是在九宮格裡,而是在3 4的格仔裡面。現在小明先下,但是他知道小花這個人很聰明,他想知道第一步下在哪乙個地方最合適,你能幫幫他嗎?input...
暑假訓練第一場D
題目 s0.n 1是乙個長度為n的字串,定義旋轉函式left s s1 n 1 s0.比如s abcd left s bcda 乙個串是對串當且僅當這個串長度為偶數,前半段和後半段一樣。比如 abcabc 是對串,aabbcc 則不是。現在問題是給定乙個字串,判斷他是否可以由乙個對串旋轉任意次得到。...
暑假集訓 個人賽第一場
g qin shi huang s national road system 題意是給你平面上n個點,每個點代表乙個城市,給你每個城市的人口,修n 1條路讓其連通。有法術可以讓其中免去其中一條路的費用。讓你求是的a b最大的時候的最小花費,其中a是免費的這條路連線的兩個城市的人口之和,b是需要花費的...