一:组队
答案:490
二:不同的字串
答案:100`
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
string s = "0100110001010001";
set<string> ans;
int main()
{
for (int i = 0; i < s.size(); i++)
for (int j = 0; j < s.size(); j++)
{
string t = s.substr(i, j);
ans.insert(t);
}
cout << ans.size();
return 0;
}
三:数列求值
答案:4659
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int mod = 10000;
int main()
{
int a = 1;
int b = 1;
int c = 3;
int d;
for (int i = 5; i <= 20190324; i++)
{
d = (a + b + c) % mod;
a = b % mod;
b = c % mod;
c = d;
}
cout << d << endl;
return 0;
}
四:数的分解
答案 40785
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int ans;
bool check(int n)
{
while (n)
{
if (n % 10 == 2 || n % 10 == 4)
return false;
n /= 10;
}
return true;
}
int main()
{
for (int i = 1; i < 2019; i++)
for (int j = i + 1; j < 2019; j++)
for (int k = j + 1; k < 2019; k++)
if (check(i) && check(j) && check(k))
if (i + j + k == 2019)
ans++;
cout << ans << endl;
return 0;
}
五:迷宫
思路 用bfs, 每次按照最小的字典序走,第一次走到终点对应的路径就是最小的字典序。
答案 DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
const int n = 30, m = 50;
struct node
{
int x, y, sum;
char p[500];
};
char map[35][55];
bool vis[35][55];
char path[200];
int dx[] = {1, 0, 0, -1};
int dy[] = {0, -1, 1, 0};
char p[] = {'D', 'L', 'R', 'U'};
void bfs()
{
queue<node> q;
q.push({1, 1, 1});
while (q.size())
{
node t = q.front();
q.pop();
int x = t.x;
int y = t.y;
int s = t.sum;
if (vis[x][y])
continue;
vis[x][y] = true;
for (int i = 0; i < 4; i++)
{
int fx = x + dx[i];
int fy = y + dy[i];
if (fx > 0 && fx <= n && fy > 0 && fy <= m && map[fx][fy] == '0' && !vis[fx][fy])
{
t.p[s] = p[i];
if (fx == n && fy == m)
{
for (int i = 1; i <= s; i++)
cout << t.p[i];
cout << s << endl;
}
node te;
te.x = fx, te.y = fy, te.sum = s + 1;
memcpy(te.p, t.p, sizeof t.p);
q.push(te);
}
}
}
}
int main()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> map[i][j];
bfs();
return 0;
}
六:特别数的和
思路
直接暴力,数据最大是10000,所以运算最大也是40000,题目给了1s,所以应该是可以过的
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int ans;
bool check(int n)
{
while (n)
{
if (n % 10 == 2 || n % 10 == 0 || n % 10 == 1 || n % 10 == 9)
return true;
n /= 10;
}
return false;
}
int n;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
if (check(i))
ans += i;
}
printf("%d\n", ans);
return 0;
}
七:外卖店的优先级
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 100010;
struct node
{
int ts, id;
bool operator<(const node &a) const
{
return a.ts > ts;
}
} a[N];
int n, m, t, ans;
int dian[10010];
int vis[10010]; //记录上一次修改的位置
bool iscode[10010]; //记录这个id是否已经被计算
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n >> m >> t;
int ts, id;
for (int i = 1; i <= m; i++)
{
cin >> ts >> id;
a[i].ts = ts;
a[i].id = id;
}
sort(a + 1, a + m + 1);
for (int i = 1; i <= m; i++)
{
int id = a[i].id;
int ts = a[i].ts;
if (!vis[id])
{
dian[id] = 2;
vis[id] = ts;
}
else if (ts == vis[id])
{
dian[id] += 2;
vis[id] = ts;
}
else
{
dian[id] -= (ts - vis[id] - 1);
dian[id] += 2;
if (dian[id] <= 0)
{
vis[id] = 0;
dian[id] = 0;
}
else
vis[id] = ts;
}
if (ts == t && !iscode[id] && dian[id] >= 5) //特判刚好在最后一个时间达到5
{
iscode[id] = true;
ans++;
}
if (t != ts && dian[id] - (t - ts - 1) >= 5 && !iscode[id]) //在最后一个时间以前达到某个值,可以让这个id一直减到t还保持在>=4
{
iscode[id] = true;
ans++;
}
}
cout << ans << endl;
return 0;
}
八:人物相关性分析
思路:双指针算法,分别扫描Alice 和 Bob
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
string s;
int n, k, ans;
bool check(int n)
{
if (s[n] >= 'a' && s[n] <= 'z')
return false;
if (s[n] >= 'A' && s[n] <= 'Z')
return false;
return true;
}
int main()
{
scanf("%d", &k);
getchar();
getline(cin, s);
int n = s.size();
string a = "Alice", b = "Bob";
int x = 5, y = 3;
int s1, s2, e1, e2;
bool flag1 = false, flag2 = false;
for (int i = 0, j = 0; i + 4 < n && j + 2 < n;)
{
if (s[i] == 'A' && s[i + 1] == 'l' && s[i + 2] == 'i' && s[i + 3] == 'c' && s[i + 4] == 'e' && (i + 5 == n || check(i + 5)) && (i == 0 || check(i - 1)))
{
s1 = i, e1 = i + 4;
flag1 = true;
}
if (s[j] == 'B' && s[j + 1] == 'o' && s[j + 2] == 'b' && ((j + 3 == n) || check(j + 3)) && (j == 0 || check(j - 1)))
{
s2 = j, e2 = j + 2;
flag2 = true;
}
if (flag1 && flag2)
{
if (s1 > e2)
{
int dis = s1 - e2 + 1;
if (dis <= k)
{
ans++;
flag2 = false;
}
else
flag2 = false;
}
else if (s2 > e1)
{
int dis = s2 - e1 + 1;
if (dis <= k)
{
ans++;
flag1 = false;
}
else
flag1 = false;
}
}
if (!flag1)
i++;
if (!flag2)
j++;
}
cout << ans << endl;
return 0;
}
九:后缀表达式
这道题比较有争议,我用的贪心,有m个减号,就相当于把m个负数变成正数,如果负数不足m个,就把最小的那几个数变成负数,然后相加。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 100010;
int a[N];
int n, m;
bool cmp(int a, int b)
{
return abs(a) > abs(b);
}
int main()
{
scanf("%d%d", &n, &m);
int s = n + m + 1;
for (int i = 0; i < s; i++)
{
scanf("%d", a + i);
}
sort(a, a + s, cmp);
for (int i = 0; i < s && m > 0; i++)
if (a[i] < 0)
m--, a[i] = -a[i];
if (m > 0)
{
for (int i = s - 1; i >= 0 && m > 0; i--)
{
a[i] = -a[i];
m--;
}
}
ll ans = 0;
for (int i = 0; i < s; i++)
{
ans += a[i];
cout << a[i] << " ";
}
cout << endl;
printf("%lld\n", ans);
return 0;
}
十:灵能传输
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 10010;
int a[N];
int n, t;
bool dif(int a, int b)
{
if (a > 0 && b < 0)
return true;
if (a < 0 && b > 0)
return true;
return false;
}
bool Same(int x, int y)
{
if (x > 0 && y > 0)
return true;
if (x < 0 && y < 0)
return true;
return false;
}
void sove(int i)
{
a[i - 1] += a[i];
a[i + 1] += a[i];
a[i] -= 2 * a[i];
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
bool zheng = false, fu = false;
for (int i = 1; i <= n; i++)
{
scanf("%d", a + i);
if (a[i] > 0)
zheng = true;
if (a[i] < 0)
fu = true;
}
if (zheng && fu)
{
bool flag = false;
do
{
flag = false;
for (int i = 2; i <= n - 1; i++)
{
//1
if (a[i] > 0 && dif(a[i + 1], a[i - 1]))
{
if (a[i - 1] < 0 && abs(a[i - 1]) > a[i] + a[i + 1])
{
sove(i);
flag = true;
}
else if (a[i - 1] > 0 && abs(a[i + 1]) > a[i] + a[i - 1])
{
sove(i);
flag = true;
}
}
//2
if (a[i] < 0 && dif(a[i + 1], a[i - 1]))
{
if (a[i - 1] > 0 && a[i - 1] > abs(a[i] + a[i + 1]))
{
sove(i);
flag = true;
}
if (a[i - 1] < 0 && a[i + 1] > abs(a[i] + a[i - 1]))
{
sove(i);
flag = true;
}
}
//3
if (Same(a[i - 1], a[i + 1]) && dif(a[i], a[i - 1]) && dif(a[i], a[i + 1]))
{
if (a[i] < 0)
{
if (a[i - 1] > abs(a[i] || a[i + 1] > abs(a[i])))
{
sove(i);
flag = true;
}
}
if (a[i] > 0)
{
if (abs(a[i - 1]) > a[i] || abs(a[i + 1]) > a[i])
{
sove(i);
flag = true;
}
}
}
}
} while (flag);
}
int ans = -0x3f3f3f3f;
for (int i = 1; i <= n; i++)
ans = max(ans, abs(a[i]));
printf("%d\n", ans);
}
return 0;
}