地址 http://acmteam.heyuantao.cn/contest.php?cid=1012
A 组成三位数
枚举第一个数,第二个数第三个数根据关系算出来,然后判断是否合法就行了。
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
int vis[10] = {0};
bool fun(int n) {
while(n) {
int c = n % 10;
if(vis[c]) return false;
vis[c] = 1;
n /= 10;
}
return true;
}
bool check(int a, int b, int c) {
memset(vis, 0, sizeof vis);
return fun(a) && fun(b) && fun(c);
}
int main() {
rep(i, 123, 987) {
int b = i * 2;
int c = i * 3;
if(check(i, b, c)) {
printf("%d %d %d\n", i, b, c);
}
}
return 0;
}
这是牛思琦的全排列做法
// http://acmteam.heyuantao.cn/problem.php?id=4104
/*签到题,没什么好说的。
不过第一次看到这道题的时候确实挺开心的,
因为以前了解了next_permutation和prev_permutation函数后
一直没机会用,哈哈哈哈
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[9]={1,2,3,4,5,6,7,8,9},cnt;
int main()
{
do
{
int t1=a[0]*100+a[1]*10+a[2];
int t2=a[3]*100+a[4]*10+a[5];
int t3=a[6]*100+a[7]*10+a[8];
if(2*t1==t2&&3*t1==t3)
cout<<t1<<" "<<t2<<" "<<t3<<endl;
}while(next_permutation(a,a+9));
return 0;
}
B New Year Candles
这就是个数学题,每b根用过的能合成一根新的,模拟一下就可以了。
#include<bits/stdc++.h>
using namespace std;
int main() {
int a,b;
scanf("%d%d", &a, &b);
int f = 0, cnt = a;
while(a >= b) {
f = a % b;
cnt += a / b;
a = a / b + f;
}
cout << cnt;
return 0;
}
**C 均分纸牌 **
这题我不会,诺姐原话:这题不是看一眼就出来了???膜拜大佬
题目中求的是最快多少次,那么你完全可以假定为最好情况,既每个大于平均数的数左边比他小的数刚好和大于平均数部分相等。因为如果大于平均数部分比左边欠的少的话,可以先通过右边更多的给他一部分。所以每个数最多只会加一次。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
int main() {
int n, a[105] = {0}, sum = 0;
scanf("%d", &n);
rep(i, 1, n) {
scanf("%d", &a[i]);
sum += a[i];
}
sum /= n;
int tot = 0, cnt = 0;
rep(i, 1, n-1) {
tot = a[i] - sum;
if(tot) {
a[i + 1] += tot;
cnt++;
}
}
cout << cnt;
return 0;
}
**D 质因数分解 **
注意判断质数时候到 i * i 就可以了,否则会超时。
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
bool isprime(int n) {
if(n & 2 == 0 && n != 2) {
return 0;
}
for(int i = 3; i * i <= n; i +=2) {
if(n % i == 0)
return 0;
}
return n>1;
}
int main() {
int n;
scanf("%d", &n);
rep(i, 2, sqrt(n)) {
if(n % i == 0)
if(isprime(i) && isprime(n / i)) {
cout << n / i << endl;
break;
}
}
return 0;
}
第二种方法,不是通解。
首先,题目中告诉我们了n是两个质数的乘积。而我们知道两个质数的最大公约数是1,即n只有这两个质数为因子(1除外),那么我们可以直接一遍遍历遇到能整除的就是答案了。
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
int main() {
int n;
scanf("%d", &n);
for(int i = 2; i * i <= n; ++i) {
if(n % i == 0) {
printf("%d", n / i);
break;
}
}
return 0;
}
**E Jury Size **
如果你看懂题目了的话,这就是一个贪心。用map,可能因为有上一年的会是负数。
当然用数组也可以,只不过你要初始化的时候先加一个比ti大的数字。题目中100及以上都可以。
#include<bits/stdc++.h>
using namespace std;
int date[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int fun(int m){
int res = 0;
for(int i = 1; i <= m; ++i) {
res += date[i];
}
return res;
}
int main(){
int n, res = 0;
cin >> n;
map<int, int> mp;
for(int i = 0; i < n; ++i ) {
int m, d, p, t;
cin >> m >> d >> p >> t;
int s = fun(m - 1) + d;
for(int j = s - t; j < s; ++j) {
mp[j] += p;
res = max(res, mp[j]);
}
}
cout << res << endl;
return 0;
}
**F Regular Bracket Sequence **
判断有多少个合法括号序列,那么首先一种思路就是用栈模拟一下。
#include<bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
stack<int> st;
int ans=0;
for(int i=0; i<s.size(); ++i) {
if(s[i]=='(')
st.emplace(i);
else{
if(!st.empty()){
ans+=2;
st.pop();
}
}
}
cout << ans;
return 0;
}
还可以对空间进行优化,因为只有左右括号,所以我们可以用一个变量记录某种括号数量。O(1)空间复杂度
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
const int maxn = 1e6;
char s[maxn];
int main() {
scanf("%s", s);
int ans = 0, cnt = 0;
for(int i = 0; i < strlen(s); ++i) {
if(s[i] == '(') ++cnt;
else if(cnt > 0) {
--cnt;
ans += 2;
}
}
printf("%d", ans);
return 0;
}
**G 合并果子 **
首先一个思路就是每次选最小的两个合并,那么整体肯定是最优的。
如果用两重for时间复杂度很高。用优先队列可以优化到O(nlogn)。
和这题 修理牧场 思路完全一样
#include<bits/stdc++.h>
#include<cmath>
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
int main() {
int n;
scanf("%d", &n);
priority_queue<int, vector<int>, greater<int>> q;
rep(i, 1, n) {
int x;
scanf("%d", &x);
q.push(x);
}
int sum = 0;
while(q.size() != 1) {
int a = q.top(); q.pop();
int b = q.top(); q.pop();
sum += a + b;
q.push(a + b);
}
printf("%d", sum);
return 0;
}