洛谷P6014 斗牛
程序员文章站
2024-03-18 21:58:46
...
题面
给定n张牌,牌大小为1~10。挑选n-2张牌加起来是10的倍数,另外两张牌的和的个位数即得分。
特别的,最后这两张牌如果和为10的倍数,则得分10.
如果没有n-2张牌能构成10的倍数,得分0。
分析
正向难做(比赛时使用的正向,总有条件没考虑到WA了),即便采取了很多的化简方式,将存在的牌数通过凑10的倍数缩小到二三十张。
反向的思路简单,如果上述条件可能,则余下的2张牌可组成牌总和的%10或%10+10。(n-2张组成了前面的10整数倍部分),%10+10也可是因为两张牌的和最大20
代码
#include <stdio.h>
#include<iostream>
using namespace std;
int card[11];
bool check(int num)//判断num可否由card组成,复杂度O(1),因为总的组合数是确定的
{
for (int i = 1; i <= 10; i++)
{
if (card[i] >= 1)for (int j = 1; j <= 10; j++)
{
if (i != j) {
if (card[j] >= 1 && (i + j == num))return true;
}
else {
if (card[j] >= 2 && (i + j == num))return true;
}
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
int n,temp,val=0;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> temp;
card[temp]++;//card[i]的值代表i牌面有多少张
val += temp;
}
//实际上需要两个牌凑出来的值就是val的个位数(或个位数+10)
if (check(val%10) ||(val>10) &&check(val%10 + 10))
{
val %= 10;
if (val%10 == 0)val += 10;
cout << val;
}
else cout << 0;
return 0;
}
正向做交了很多发。。。又臭又长。。。
反向一发AC
上一篇: 2021.03.06【NOIP提高B组】模拟 总结
下一篇: 本以为是分治法 谁知道