如果題目版權限制,不能發表該題解,請私信,我會立刻刪除博客。
題目描述
但是有一天小W發現鐘錶似乎壞了,顯示了一個不可能存在的時間“98:23:00”,小W希望改變最少的數字,使得電子時鐘顯示的時間爲一個真實存在的時間,譬如“98:23:00”通過修改第一個’9’爲’1’,即可成爲一個真實存在的時間“18:23:00”。修改的方法可能有很多,小W想知道,在滿足改變最少的數字的前提下,符合條件的字典序最小的時間是多少。其中字典序比較爲用“HHMMSS”的6位字符串進行比較。
輸入描述:
每個輸入數據包含多個測試點。每個測試點後有一個空行。 第一行爲測試點的個數T(T<=100)。 每個測試點包含1行,爲一個字符串”HH:MM:SS”,表示鐘錶顯示的時間。
輸出描述:
對於每個測試點,輸出一行。如果鐘錶顯示的時間爲真實存在的時間,則不做改動輸出該時間,否則輸出一個新的”HH:MM:SS”,表示修改最少的數字情況下,字典序最小的真實存在的時間。
輸入
2
19:90:23
23:59:59
輸出
19:00:23
23:59:59
【 網易互娛2018校招遊戲研發工程師在線筆試 A】【水題】
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int h, m, s;
char S[10];
int a[10], b[10];
struct ANS
{
int h, m, s;
}ans;
//簡單做法
void simple()
{
int h, m, s;
scanf("%d:%d:%d", &h, &m, &s);
if (h >= 24)h %= 10;
if (m >= 60)m %= 10;
if (s >= 60)s %= 10;
printf("%02d:%02d:%02d\n", h, m, s);
}
//複雜暴力做法
void complex()
{
scanf("%s", S);
a[0] = S[0] - 48;
a[1] = S[1] - 48;
a[2] = S[3] - 48;
a[3] = S[4] - 48;
a[4] = S[6] - 48;
a[5] = S[7] - 48;
//60 * 60 * 24
int ansdif = inf;
for (int i = 0; i < 24; ++i)
{
b[0] = i / 10;
b[1] = i % 10;
for (int j = 0; j < 60; ++j)
{
b[2] = j / 10;
b[3] = j % 10;
for (int k = 0; k < 60; ++k)
{
b[4] = k / 10;
b[5] = k % 10;
int dif = 0;
for (int u = 0; u <= 5; ++u)
{
dif += (a[u] != b[u]);
}
if (dif < ansdif)
{
ansdif = dif;
ans = { i,j,k };
}
}
}
}
printf("%02d:%02d:%02d\n", ans.h, ans.m, ans.s);
}
int main()
{
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
simple();
}
return 0;
}
/*
【題意】
略
【分析】
可以直接暴力枚舉所有時刻取一個最優的。
也可以對時、分、秒 三個數整體判定,如果不合法,把數的十位數變成0即可。
【時間複雜度&&優化】
O(1)
*/
題目描述
輸入描述:
輸入的第一行爲一個正整數T,表示測試數據組數。 接下來有T組數據。每組數據的第一行包括兩個整數m和n,表示字符迷陣的行數和列數。接下來有m行,每一行爲一個長度爲n的字符串,按順序表示每一行之中的字符。再接下來還有一行包括一個字符串,表示要尋找的單詞。 數據範圍: 對於所有數據,都滿足1<=T<=9,且輸入的所有位於字符迷陣和單詞中的字符都爲大寫字母。要尋找的單詞最短爲2個字符,最長爲9個字符。字符迷陣和行列數,最小爲1,最多爲99。 對於其中50%的數據文件,字符迷陣的行列數更限制爲最多爲20。
輸出描述:
對於每一組數據,輸出一行,包含一個整數,爲在給定的字符迷陣中找到給定的單詞的合法方案數。
輸入
3 10 10 AAAAAADROW WORDBBBBBB OCCCWCCCCC RFFFFOFFFF DHHHHHRHHH ZWZVVVVDID ZOZVXXDKIR ZRZVXRXKIO ZDZVOXXKIW ZZZWXXXKIK WORD 3 3 AAA AAA AAA AA 5 8 WORDSWOR ORDSWORD RDSWORDS DSWORDSW SWORDSWO SWORD
輸出
4 16 5
【 網易互娛2018校招遊戲研發工程師在線筆試 B】【水題】
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 2020, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
char s[N][N];
int n, m;
char w[N];
int main()
{
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
MS(s, 0);
scanf("%d%d", &n, &m);
for (int i = 0; i < n; ++i)
{
scanf("%s", s[i]);
}
scanf("%s", w);
int ans = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
bool flag = 1;
for (int k = 0; w[k]; ++k)
{
if (s[i + k][j] != w[k])
{
flag = 0;
break;
}
}
ans += flag;
//
flag = 1;
for (int k = 0; w[k]; ++k)
{
if (s[i][j + k] != w[k])
{
flag = 0;
break;
}
}
ans += flag;
//
flag = 1;
for (int k = 0; w[k]; ++k)
{
if (s[i + k][j + k] != w[k])
{
flag = 0;
break;
}
}
ans += flag;
}
}
printf("%d\n", ans);
}
return 0;
}
/*
【trick&&吐槽】
邊界用'\0'封閉就好啦
*/
題目描述
輸入描述:
每個輸入數據僅包含一個測試點。 輸入第一行首先給出流量記錄的總條目數 N <= 100000。接下來N行,每行對應了一個流量記錄。每條流量記錄的格式爲 月/日/年 時/分/秒 流量: MM/DD/YYYY hr:mi:se FLOWi 表示該時刻流量統計軟件記錄下了FLOWi (0 <= FLOWi <= 10000且爲整數)兆的流量。 輸入數據保證N條流量記錄的時間是遞增,且同一時間沒有重複的流量記錄。 接下來一行給出小易查詢總流量的數目M <= 100000。接下來M行,每行表示第mj次查詢的起始和結束時間點。格式如下: MM/DD/YYYY hr:mi:se MM/DD/YYYY hr:mi:se 輸入數據保證每次查詢的結束時間一定不會早於起始時間。所有的輸入數據均合法。
輸出描述:
輸出結果包含M行,每行對應第mj次查詢,每次查詢的結果爲包含起始和結束兩個時刻的總流量。
輸入
5 02/12/2016 00:00:00 10 02/18/2016 12:00:00 45 02/18/2016 23:59:59 8 02/19/2016 08:00:15 20 02/22/2016 13:00:00 31 4 01/01/2014 00:00:00 01/01/2017 00:00:00 11/11/2016 11:11:11 02/14/2017 00:05:20 02/12/2016 00:00:00 02/18/2016 23:00:00 02/18/2016 12:00:00 02/18/2016 12:00:00
輸出
114 0 55 45
【 網易互娛2018校招遊戲研發工程師在線筆試 C】【排序+前綴和】
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n, m;
struct A
{
int mon, d, y, h, m, s;
int sum;
bool operator < (const A & b)const
{
if (y != b.y)return y < b.y;
if (mon != b.mon)return mon < b.mon;
if (d != b.d)return d < b.d;
if (h != b.h)return h < b.h;
if (m != b.m)return m < b.m;
return s < b.s;
}
}a[N];
int sum[N];
int main()
{
while(~scanf("%d", &n))
{
for (int i = 1; i <= n; ++i)
{
int mon, d, y, h, m, s, sum;
scanf("%d/%d/%d %d:%d:%d %d", &mon, &d, &y, &h, &m, &s, &sum);
a[i] = { mon, d, y, h, m, s, sum };
}
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i)
{
sum[i] = sum[i - 1] + a[i].sum;
}
scanf("%d", &m);
for (int i = 1; i <= m; ++i)
{
int mon, d, y, h, m, s;
scanf("%d/%d/%d %d:%d:%d", &mon, &d, &y, &h, &m, &s);
A lft = { mon, d, y, h, m, s};
scanf("%d/%d/%d %d:%d:%d", &mon, &d, &y, &h, &m, &s);
A rgt = { mon, d, y, h, m, s };
int l = lower_bound(a + 1, a + n + 1, lft) - a - 1;
int r = upper_bound(a + 1, a + n + 1, rgt) - a - 1;
int ans = sum[r] - sum[l];
printf("%d\n", ans);
}
}
return 0;
}
/*
【題意】
略
【分析】
只要按照時間順序排序求個前綴和,然後二分尋找區間範圍,用前綴和快速求解
*/
題目描述
技能和普攻都有冷卻時間,普攻的冷卻時間都爲1秒,而你的3個技能擁有相同的冷卻時間cd秒。冷卻時間爲cd指的是:若你在第t1秒釋放了該技能,那麼在t1+cd秒纔可以再次釋放。所以普攻可以在每秒釋放,但技能卻不一定。你還有一個被動技能,每擊殺一個敵人,則全部技能的冷卻時間清零。
你是個執着的人,每次選擇一個敵人後就不再更改目標直到打死這個敵人或自己死亡。
在每一秒的開始,如果你沒有攻擊目標(戰鬥開始時或上一秒剛擊殺上一個目標),則選擇一個攻擊目標,否則繼續鎖定上一秒你的攻擊目標。然後選擇一個技能或普攻來攻擊該目標,同時所有還活着的敵人也會攻擊你。接下來所有人同時結算扣血,血量小於等於0的單位認爲死亡。一個攻擊力爲atk的技能或普攻,會造成atk的血量損失。
已知3名敵人的當前血量和攻擊力,以及你每一個技能的攻擊力和普攻攻擊力,問你是否可以完成這個漂亮的三殺。如果可以,那麼完成三殺後你最多可以剩多少血量?(注意:同歸於盡不算完成三殺)
輸入描述:
輸入的第一行是一個正整數T,表示樣例數。 接下來是T個樣例,每個樣例的第一行是3個正整數hp, atk,cd,分別表示你的當前生命、普攻攻擊力以及技能冷卻時間。第二行是3個正整數x1, x2, x3,分別表示你的3個技能的攻擊力。第三行是6個正整數hp1, y1, hp2, y2, hp3, y3,分別表示3個敵方英雄的血量和普攻攻擊力。 對於30%的數據,所有血量不超過500,所有技能和普攻攻擊力不超過50;對於100%的數據,所有血量不超過50000,所有技能和普攻攻擊力不超過100。技能的冷卻時間1 <= cd <= 10。
輸出描述:
對於每一個樣例,輸出一個整數,表示完成三殺後你最多還剩多少血量。如果不能完成,輸出-1。
輸入
2 254 25 9 31 21 15 86 6 196 1 249 10 119 26 5 46 27 13 219 6 169 20 50 20
輸出
68 -1
備註:
樣例1: 先攻擊第一個敵人,使用1次技能1和3次普攻,共花費4秒擊殺; 然後攻擊第三個敵人,先使用1次技能1和8次普攻,此時使用一次技能1(剛好冷卻結束)或普攻,共花費10秒; 最後攻擊第二個敵人,先使用1次技能1,然後7次普攻,共花費8秒。 受到的總傷害爲(6+1+10)*4 + (1 + 10) * 10 + 1 * 8 = 186,所以最終還剩68血量。 樣例2: 無論怎樣選擇攻擊策略,都無法完成三殺。
【 網易互娛2018校招遊戲研發工程師在線筆試 D】【貪心+全排列】技能有CD,選擇順序和施法方案,最小傷害損失三殺
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int hp, atk, cd;
int x1, x2, x3;
struct A
{
int hp, atk;
}a[3];
int p[3];
int skl[3], cdrst[3], turn[3], g;
int solve(int HP)
{
int atksum = 0;
for (int i = 0; i < 3; ++i)
{
int atk = a[p[i]].atk;
atksum += atk;
}
//KILL
for (int i = 0; i < 3; ++i)
{
int hp = a[p[i]].hp;
int atk = a[p[i]].atk;
int tim = turn[p[i]];
HP -= tim * atksum;
atksum -= atk;
}
return HP;
}
int main()
{
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
scanf("%d%d%d", &hp, &atk, &cd);
scanf("%d%d%d", &skl[0], &skl[1], &skl[2]);
g = 3; sort(skl, skl + 3);
reverse(skl, skl + 3);
while (g && skl[g - 1] <= atk)--g;
//find order skill
for (int i = 0; i < 3; ++i)
{
scanf("%d%d", &a[i].hp, &a[i].atk);
turn[i] = 0;
int hp = a[i].hp;
for (int j = 0; j < g; ++j)cdrst[j] = 0;
while (hp > 0)
{
++turn[i];
for (int j = 0; j < g; ++j)--cdrst[j];
bool flag = 0;
for (int j = 0; j < g; ++j)if (cdrst[j] <= 0)
{
hp -= skl[j];
cdrst[j] = cd;
flag = 1;
break;
}
if (!flag)hp -= atk;
}
int pause = 1;
}
//find order player
int ans = -1;
for (int i = 0; i < 3; ++i)p[i] = i;
do
{
gmax(ans, solve(hp));
} while (next_permutation(p, p + 3));
printf("%d\n", ans);
}
return 0;
}
/*
【trick&&吐槽】
這種做法有問題,找到了反例,但是通過了比賽的所有測試數據。
*/
題目描述
1. "0"和"1"是合法表達式;
2. 如果x和y是合法表達式,那麼"(x|y)"和"(x&y)"都是合法表達式
其中,|
和&
分別是與運算符和或運算符。
給定一個合法表達式,求該表達式最終的值。如果可以修改這個表達式的操作符:將|
修改爲&
,將&
修改爲|
,求最少需要修改多少個操作符可以修改表達式最終的值?
輸入描述:
第一行是一個正整數T(T <= 20)。接下來T行,每一行是一個表達式。表達式不含空格,且輸入保證該表達式是一個合法表達式。 對於30%的數據,表達式的長度不超過500; 對於100%的數據,表達式的長度不超過150000。
輸出描述:
T行,每一行包含兩個整數x, y,用空格隔開,分別表示表達式的值,以及最少需要修改多少個操作符可以修改表達式的值。如果無法通過修改操作符修改表達式的值,則y輸出-1。
輸入
3 ((0|1)|(0|0)) ((0|0)&(0|0)) (((1|0)|(0&0))|((1|0)|(0|1)))
輸出
1 1 0 -1 1 2
備註:
樣例1:將表達式修改爲((0&1)|(0|0))或((0|1)&(0|0)) 樣例2:無論怎樣修改,都無法將表達式結果變爲1 樣例3:有多個方案,其中一個爲(((1&0)|(0&0))&((1|0)|(0|1))),但最少需要修改2個操作符
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1.5e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
char s[N];
int sta[N], top;
int match[N];
int val[N];
int check(int l, int r)
{
if (~val[l])return val[l];
if (l == r)return val[l] = (s[l] - '0');
if (match[l] == r) return val[l] = check(l + 1, r - 1);
int lm = match[l];
int rm = match[r];
int lv = check(l, lm);
int rv = check(rm, r);
char sig = s[lm + 1];
if (sig == '|')
{
return val[l] = (lv | rv);
}
else//if(sig == '&')
{
return val[l] = (lv & rv);
}
}
int GET1(int l, int r)
{
if (val[l] == 1)return 0;
if (l == r)return s[l] == '1' ? 0 : inf;
if (match[l] == r) return GET1(l + 1, r - 1);
int lm = match[l];
int rm = match[r];
int lv = GET1(l, lm);
int rv = GET1(rm, r);
char sig = s[lm + 1];
if (sig == '|')//good
{
return min(lv, rv);
}
else//if(sig == '&')//bad
{
return min(lv + rv, min(lv, rv) + 1);
}
}
int GET0(int l, int r)
{
if (val[l] == 0)return 0;
if (l == r)return s[l] == '0' ? 0 : inf;
if (match[l] == r) return GET0(l + 1, r - 1);
int lm = match[l];
int rm = match[r];
int lv = GET0(l, lm);
int rv = GET0(rm, r);
char sig = s[lm + 1];
if (sig == '&')//good
{
return min(lv, rv);
}
else//if(sig == '&')//bad
{
return min(lv + rv, min(lv, rv) + 1);
}
}
int main()
{
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
MS(val, -1);
scanf("%s", s + 1); n = strlen(s + 1);
top = 0;
for (int i = 1; i <= n; ++i)
{
if (s[i] == '(')
{
sta[++top] = i;
}
else if(s[i] == ')')
{
match[i] = sta[top];
match[sta[top]] = i;
--top;
}
else if (s[i] == '0' || s[i] == '1')
{
match[i] = i;
}
}
int val = check(1, n);
int ans;
if (val == 1)//嘗試由true轉false
{
ans = GET0(1, n);
}
else//嘗試由false轉true
{
ans = GET1(1, n);
}
if (ans >= inf)ans = -1;
printf("%d %d\n", val, ans);
}
return 0;
}
/*
【trick&&吐槽】
好好看題,每次生成邏輯表達式的疊加之後,外面都會加括號的。
知道了數據的生成方式之後,解題會變得更加容易!
【題意】
略
【分析】
1,我們處理每個位置的相應匹配位置
2,通過迭代的方式可以求出整體表達式的值
3,我們求出每個區間變值爲0或1的最少符號修改次數,然後處理好合並過程下需要的修改次數(詳見代碼)
【時間複雜度&&優化】
O(n)
*/