题目链接
http://exam.upc.edu.cn/contest.php?cid=1475
题解:
A:模拟直接做
B:折纸 折好几下 在一个地方打孔,问能打多厚,其实应该是问有多少张纸
我感觉模拟就是了
就是每次折叠完之后重塑新的数组。然后再模拟。。判断折过去盖不住,折过去盖住了两种情况。
C.等差数列
每一层楼的租金是这层楼的层数,现在有b的租金,问能租下的最长连续楼层(输出最低楼和层数),而且必须恰好用完。
思路:
这题利用等差公式求和。 a1*n+n*(n-1)/2=S,化简公式。
2n*a1+n^2-n-2s=0,n^2+(2*a1-1)n-2s=0,n的数量较小,我们枚举n就好,又因为,根据韦达定理,两根相乘为2s,两根相加为2*a1-0*n的因数(可大可小)
这样我们对于sqrt(2*n)的情况下,枚举小因数和大因数即可。
D题
大意:Minato Mirai足球协会将其年度锦标赛作为单场循环赛举办,每场比赛对阵所有其他球队。与许多其他的橄榄球循环赛不同,比赛从未在本次比赛中获得平局。当常规时间比赛是平局时,将播放加时赛,并且当再次打平时,将进行点球大战以决定胜者。
如果两支或更多球队在循环赛中赢得了最多的比赛,那么他们之间会进行一场季后赛以决定冠军。但是,如果球队的数量是一个奇数,那么所有球队都可能拥有相同数量的胜负,在这种情况下,所有球队都参加了季后赛,在这里称为“全季后赛”。
现在,一些锦标赛比赛已经开始,我们知道他们的结果。是否需要完整的季后赛可能取决于剩余比赛的结果。编写一个程序,计算导致完整季后赛的剩余比赛的赢/输组合模式的数量。
思路感觉是个搜索题
设mpp[a][b]表示a击败b,win[i]表示第i只队伍赢了几次
lose[i]表示第i只队伍输了几次
然后搜索
1.每只队伍赢得次数相等那就是(n-1)/2
2.然后搜索试试
3.每次搜索要把lose[i]>(n-1)/2和win[i]>(n-1)/2的减掉
codeA:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000000005;
int a[5000000];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int abv=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
abv+=a[i];
}
abv/=n;
int cnt=0;
for(int i=1;i<=n;i++)
{
if(abv>=a[i])cnt++;
}
cout<<cnt<<endl;
}
}
codeC:
#include<bits/stdc++.h>
using namespace std;
int minfloor;
//a1*n+n*(n-1)=s
void judge(int n)
{
int flag = 0;
for (int i = sqrt(2 * n); i; i--)
{
if (2 * n%i == 0)
{
minfloor = (2 * n - i * i + i) / (2 * i);
if (minfloor*i + (i - 1)*i / 2 == n)
{
flag = 1;
cout << minfloor << " " << i << endl;
break;
}
int b = n / i;
minfloor = (2 * n - b * b + b) / (2 * b);
if (minfloor*i + (i - 1)*i / 2 == n)
{
flag = 1;
cout << minfloor << " " << i << endl;
break;
}
}
}
if (!flag)
{
cout << n << " " << 1 << endl;
}
}
int main()
{
int n;
while (scanf("%d", &n) != EOF&&n)
{
judge(n);
}
}
codeD:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
int mp[1000][1000];
int win[1000];
int lose[1000];
int ans;
void dfs(int a, int b)
{
if (a == n && b == n)
{
ans++;
return;
}
if (b>n)
{
a++;
b = 1;
}
if (mp[a][b] != -1 || a == b)
{
dfs(a, b + 1);
}
else
{
if ((win[a]<(n - 1) / 2)&&lose[b]<(n - 1) / 2)
{
mp[a][b] = 1;
mp[b][a] = 0;
win[a]++;
lose[b]++;
dfs(a, b + 1);
mp[a][b] = -1;
mp[b][a] = -1;
win[a]--;
lose[b]--;
}
if (win[b]<(n - 1) / 2&&lose[a]<(n - 1) / 2)
{
mp[a][b] = 0;
mp[b][a] = 1;
win[b]++;
lose[a]++;
dfs(a, b + 1);
mp[a][b] = -1;
mp[b][a] = -1;
win[b]--;
lose[a]--;
}
}
}
int main()
{
int a, b;
while (scanf("%d%d", &n, &m) && n!=0)
{
memset(mp, -1, sizeof(mp));
memset(win, 0, sizeof(win));
memset(lose, 0, sizeof(lose));
for (int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
mp[a][b] = 1;
mp[b][a] = 0;
win[a]++;
lose[b]++;
}
ans = 0;
int flag = 0;
for (int i = 1; i <= n; i++)
{
if (win[i]>(n - 1) / 2)
{
flag = 1;
printf("0\n");
break;
}
if (lose[i] > (n - 1) / 2)
{
flag = 1;
printf("0\n");
break;
}
}
if (flag == 1)continue;
dfs(1, 1);
printf("%d\n", ans);
}
return 0;
}