校内程序设计大赛
一个普通的985,一个普通的程序设计大赛 个人比较菜,参加比赛练练手
这个比赛一共有五天(五一休息的那五天),每天发布两道编程题和一些趣味题,不是十分严格,因为基本没有时间限制,每天11点 左右公布编程题,下午五点公布趣味题,当天晚上12点之前提交即可
Day 1
编程题 1
编程题 2
第一题代码
#include <iostream>
using namespace std;
int main()
{
int n;
int y = 0;
cin >> n;
int a[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
if (a[0] != 0 || a[1] != 1)
{
cout << "false";
}
int x = a[n - 1] - a[n - 2];
for (int i = n - 2; i > 0; i--)
{
int p = a[i] - a[i - 1];
if (p <= x + 1)
{
y = y + 1;
continue;
}
else
{
cout << "false";
break;
}
}
if (y == n - 2)
cout << "true";
return 0;
}
这个题我觉得应该还算简单吧,我也不知道我做的有没有漏洞,就从后面往前面推呗,然后再多几个硬性条件比如第一跳必须是1。
第二题代码
#include <iostream>
using namespace std;
int main()
{
double x1, y1, z1, p1;
double x2, y2, z2, p2;
cin >> x1 >> y1 >> z1 >> p1;
cin >> x2 >> y2 >> z2 >> p2;
double k1, k2;
double b1, b2;
double m, n;
if (x1 == z1 && x2 == z2 && x1 == x2)
{
cout << "{" << x1 << ",";
cout << "0";
cout << "}";
}
else if (x1 == z1 && x2 == z2 && x1 != x2)
{
cout << " {} (no intersection)";
}
else if (y1 == p1 && y2 == p2 && y2 == y1)
{
cout << "{";
cout << "0";
cout << ",";
cout << y1;
cout << "}";
}
else if (y1 == p1 && b2 == p2 && y2 != y1)
{
cout << " {} (no intersection)";
}
else if (x1 == z1 && y2 == p2)
{
cout << "{" << x1 << "," << y2 << "}";
}
else if (y1 == p1 && x2 == z2)
{
cout << "{" << x2 << "," << y1 << "}";
}
else
{
k1 = (p1 - y1) / (z1 - x1);
k2 = (p2 - y2) / (z2 - x2);
b1 = p1 - k1 * z1;
b2 = p2 - k2 * z2;
if (k1 == k2 && b1 == b2)
{
if (x1 > x2)
{
cout << "{" << x1 << ","
<< y1
<< "}";
}
else
{
cout << "{" << x2 << ","
<< y2
<< "}";
}
}
else if (k1 == k2 && b1 != b2)
{
cout << " {} (no intersection)";
}
else
{
n = (b2 - b1) / (k1 - k2);
m = k1 * n + b1;
cout << "{" << n << "," << m << "}";
}
}
return 0;
}
这个题感觉说难吧也不难,好像是初中数学题,但是情况还是蛮复杂的,更好的方法我也不会,我就把所有情况都考虑一遍,也不知道有没有漏下的条件,这应该算是暴力方法?
趣味题
这几道都考验逻辑思维能力,还是很有趣的,当时做这些的时候我才北京西站等待回家的高铁,当许多高铁、动车都延误、取消了,很幸运我回家的高铁才延误了一个多小时。
第一题
第一次,花花看到的一定不是1,否则他可以猜出自己头上是2;
第一次,小明看到的也不是1,同时,由于花花刚才说了“不知道”,小明可以猜到自己头上不是1,在这种情况下,小明仍说不知道,说明小明看到的不是2,(否则若小明看到2,自己头上又不是1,则他可以猜到自己头上是3);
第二轮,此时花花知道自己头上不是1和2(无论他头上是1还是2,小明都会在第一轮猜出),假如他看到小明头上是2,则可猜出自己是3,若他看到小明头上是3,就能猜出自己头上是4,而他现在猜不出,说明他看到的不是2也不是3;
第二轮,小明知道自己头上不是1,2,3,如果他看到了3,就可以猜出自己头上是4,如果他看到了4,就可以猜出自己头上是5,因此小明看到的不是3和4;
第三轮,由于第二轮小明没猜出,花花就知道了自己头上不是1,2,3,4,这个时候,如果他看到了4就会猜出自己头上是5,如果看到了5,就会猜出自己头上是6,因此他看到的不是4和5;
第三轮,小明知道自己头上不是1,2,3,4,5,他看到的一定不是5,6,否则这一轮他可以猜出了;
第四轮,花花已知自己头上不是1,2,3,4,5,6,而他这回猜到了,说明他看到小明头上一定是6或7,如果小明的头上的数大于7,则这一轮花花是猜不出的,如果他看到的6,则说明自己头上是7,若他看到的是7,则自己头上是8;
第四轮,小明当然可以猜出自己头上的数字,因为他知道,他的数字一定比花花的数字小1,因为若他的数字比花花大1的话,最终应该是小明先猜出来。
第二题
这个应该比第一题简单,就直接假设就好了,只要记住脑子有问题的狼人和脑子没问题的人说的是正确的,脑子没问题的狼和脑子有问题的人说的是假的就可以了。
(小飞飞是狼人)
第三题
1113122110
这个我不会,网上找的答案,大家可以讨论讨论
Day 2
编程题 1
编程题 2
第一题代码
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll INF = 1e9;
struct node
{
ll to;
ll v;
ll next;
} edge[2000000];
struct enode
{
ll dis;
ll to;
};
struct train
{
ll to;
ll val;
} tnode[1000000];
bool operator<(const enode a, const enode b)
{
return a.dis > b.dis;
}
ll head[1000000], cnt, dis[120000], vis[120000], in[1000000];
void addedge(int a, int b, int val)
{
cnt++;
edge[cnt].next = head[a];
edge[cnt].to = b;
edge[cnt].v = val;
head[a] = cnt;
}
void dij(ll start, ll n)
{
for (int i = 1; i <= n; i++)
{
dis[i] = INF;
}
dis[start] = 0;
priority_queue<enode> q;
q.push(enode{0, start});
while (!q.empty())
{
enode x = q.top();
q.pop();
int u = x.to;
/*这一步很重要,因为有铁路的原因,某点可能会多次进入队列
那么如果没有这一步,下面的循环就要多跑好多次,而且会导致
后面记录最短路条数被多记录,当时死活没有发现*/
if (vis[u])
{
continue;
}
vis[u] = 1;
for (int i = head[u]; i != 0; i = edge[i].next)
{
if (dis[edge[i].to] == edge[i].v + dis[u])
{
in[edge[i].to]++; //记录最短路个数
}
if (!vis[edge[i].to] && dis[edge[i].to] > edge[i].v + dis[u])
{
dis[edge[i].to] = edge[i].v + dis[u];
in[edge[i].to] = 1; //每次更新一次最短路,就要把最短路条数更新成1
q.push(enode{dis[edge[i].to], edge[i].to});
}
}
}
}
int main()
{
ll n, m, k;
in[1] = 1;
scanf("%lld%lld%lld", &n, &m, &k);
while (m--)
{
ll b, e, v;
scanf("%lld%lld%lld", &e, &b, &v);
addedge(b, e, v);
addedge(e, b, v);
}
for (int i = 1; i <= k; i++)
{
scanf("%lld%lld", &tnode[i].to, &tnode[i].val);
addedge(1, tnode[i].to, tnode[i].val);
addedge(tnode[i].to, 1, tnode[i].val);
}
dij(1, n);
int num = 0;
for (int i = 1; i <= k; i++)
{
ll j = tnode[i].to;
ll w = tnode[i].val;
if (dis[j] < w)
{
num++;
}
if (dis[j] == w && in[j] != 1)
{
num++;
in[j]--;
}
}
cout << num;
return 0;
}
第二题代码
对不起大家,第二题我愣是没看懂题,反复读了好多遍,但我还是不懂题目的意思(5555555
趣味题
第一题
大家要仔细阅读题,要注意那个老妇人是如何发现假钞的,她是通过颜色的对比发现假钞的,说明给假钞的那个人只给了老妇人一张100元,这样的话老妇人就无法发现他给的是假钞了。所以答案就是第一个人咯。
第二题
是个脑筋急转弯
那个人是倒着走的
第三题
我觉得是1.会计 2.女作家 3.总裁 4.书记
不一定正确,因为也没有公布答案
后续的明后天更新