第十七届中国计量大学程序设计竞赛(同步赛)(B,C,F,I,K题解)
B.Broken Pad
大致题意:给你t组牌,每组牌有俩副牌,问从第一副牌到第二副牌至少需要操作几次?
操作的方式有2种:
-
选择一张牌(输出该牌在原数组的位置),这张牌与这张牌之后的所有牌都会反选(原来选中的牌,现在不选中;原来没选中的牌,现在选中)
-
按空格键(输出0),所有的牌都会变成未选中的状态。
思路:模拟,比较只进行操作1与先进行操作1再进行操作2所需的操作数,选中小的即可。
ac代码:
#include <iostream> #include<cstdio> #include<algorithm> using namespace std; int main() { int t; scanf("%d", &t); while(t--) { string s, str; cin>>s; cin>>str; int cnt = 0; //翻转的次数 for(int i = 0; i < s.size(); i++) { if((s[i] == str[i] && cnt % 2 == 0) || (s[i] != str[i] && cnt % 2 == 1)) //字母相同 { continue; } else cnt++; } int tot = 1; for(int i = 0; i < str.size(); i++) { if(('0' == str[i] && tot % 2 == 1) || ('0' != str[i] && tot % 2 == 0)) //字母相同 { continue; } else tot++; } if(cnt < tot) { cnt = 0; int flag = 0; for(int i = 0; i < s.size(); i++) { if((s[i] == str[i] && cnt % 2 == 0) || (s[i] != str[i] && cnt % 2 == 1)) //字母相同 { continue; } else { if(!flag) flag = 1; else printf(" "); printf("%d", i + 1); cnt++; } } } else { printf("0"); tot = 1; for(int i = 0; i < str.size(); i++) { if(('0' == str[i] && tot % 2 == 1) || ('0' != str[i] && tot % 2 == 0)) //字母相同 { continue; } else{ printf(" %d", i + 1); tot++; } } } printf("\n"); } return 0; }
C:Cook Steak
大致题意:ZJH需要煎T块牛排,对于每一块牛排,有n到工序,每道工序都有严格的温度区间,为了牛排好吃,ZJH需要将温度上升或者降低到对应温度区间才能进行煎,每道工序需要1分钟,每升高或降低1°也需要1分钟,初始温度为0°,问至少需要多少分钟才能煎好这块牛排。
思路:贪心,如果温度在下一个工艺的温度区间内,则直接煎,否则,如果离左端点近那就把温度上升到左端点,离右端点近,就把温度下降到右端点。
ac代码:
#include <iostream> #include<cstdio> #include<algorithm> using namespace std; int main() { int t; scanf("%d", &t); while(t--){ int n; scanf("%d", &n); long long tot = 0ll; int temp = 0; for(int i = 1; i <= n; i++){ int l, r; scanf("%d%d", &l, &r); if(temp >= l && temp <= r) continue; if(temp < l) tot += (l - temp), temp = l; else tot += (temp - r), temp = r; } printf("%lld\n", tot + n); } return 0; }
F.Flag Scramble Competition
根据大数据分析:在一段足够长的段落中,e的出现频率最高
#include<cstdio>
int main()
{
printf("e\n");
return 0;
}
I.Isolated Pointset
大致题意:给你N个孤立的点的点集,判断是否能从任意俩个点中画一条中垂线,使得其中至少一个点在中垂线上。
思路:N=3的时候,构成一个正三角形时,刚好满足这个条件,那么当N>3时,我们只需要构造成类似于下图(由很多个正三角形组成的梯形即可),肯定满足条件,当然小于3时,连中垂线都没有,当然不满足
ac代码:
#include<cstdio>
int main()
{
int n;
scanf("%d", &n);
while(n--){
int a;
scanf("%d", &a);
if(a >= 3)
printf("Yes\n");
else
printf("No\n");
}
}
K.Known-Well Palindrome Date-Easy Version
大致题意:每行有几个身份证号,找到 8个回文数字,回文数字得是有意义的日期,求每一行的个数
思路:模拟,找出下列条件的8位数字即可
-
回文数
-
是有效的日期(时间需要在0001.1.1~9999.12.31号之间)
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
bool leap(int y)//判断是否为闰年
{
//能被400整除或者 能被4整除但不能被100整除
if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0))
return true;
else
return false;
}
bool check(string s)//判断8个字符的回文日期是否有效
{
int date[20] = {0, 31, 28, 31,30, 31, 30, 31, 31, 30, 31, 30, 31};
int y, m, d;
y = m = d = 0;
for(int i = 0; i < 4;i++)
y = y * 10 + (s[i] - '0');
for(int i = 4; i < 6; i++)
m = m * 10 + (s[i] - '0');
for(int i = 6; i < 8; i++)
d = d * 10 + (s[i] - '0');
if(y >= 1 && y <= 9999 && m >= 1 && m <= 12 && d >= 1)
{
if(leap(y))
{
if((d <= date[m] && m != 2) ||(d <= date[m] + 1 && m == 2))
return true;
}
else if(d <= date[m])
return true;
}
return false;
}
bool Palindrome(string s)
{
for(int i = 0; i < s.size() / 2; i++)
{
if(s[i] != s[s.size() - i - 1])
return false;
}
return true;
}
int main()
{
string s;
getline(cin, s);
while(s[0] != '#')
{
int cnt = 0;
//一定要判断一下字符串的长度小于8的时候,不然会数组越界
if(s.size() < 8){
printf("0\n");
getline(cin, s);
continue;
}
for(int i = 0; i <= s.size() - 8 ; i++)
{
string str = s.substr(i, 8);
if(Palindrome(str) && check(str))
cnt++;
}
printf("%d\n", cnt);
getline(cin, s);
}
return 0;
}