A. Odd Palindrome
题意 : 回文子串长度为奇数 输出Odd 否则 输出Ornot
思路 : 实际上若字符串长度为奇数输出Odd 偶数出Or not
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
while(cin >>s){
if(s.size() % 2 != 0)
cout <<"Odd." <<endl;
else
cout <<"Or not." <<endl;
}
}
C. Fear Factoring
题意 : 输入数字a, b。求出a, b之间数字因数和 的 和
思路:分块除法 注意此题卡ull
代码1:
#define ull unsigned long long
using namespace std;
ull f(ull n)
{
ull ans=0;
ull left,right;
for(left = 1; left <= n; left = right + 1){
right = n / (n / left);
ans += (n / left) * (left + right) * (right-left+1)/2;
//这里用的是等差数列 left是首项,right是末项
}
return ans;
}
int main(){
ull a,b;
while(~scanf("%llu%llu", &a, &b))
printf("%llu\n", f(b)-f(a-1));
return 0;
代码2
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define Maxn 1000005
#define LL unsigned long long
using namespace std;
LL calc(LL n) {
LL Ans = 0;
for(LL l=1; l<=n; l++) {
LL t = n / l;
LL r = n / t;
Ans += (l + r) * (r - l + 1) / 2 * t;
l = r;
}
return Ans;
}
int main() {
LL a,b,Ans = 0;
while(scanf("%lld %lld",&a,&b) != EOF) {
cout << calc(b) - calc(a - 1) << endl;
}
return 0;
}
E. Straight Shot
题意 : 一道物理题,机器人从左边飞到右边 过人行道时有竖直分量的速度影响机器人,给定飞行的方向,使机器人可以飞到右边,求飞到右边的时间
思路:水平与竖直列出啊方程 注意sidewalk的速度是加到Vr上的
代码 :
#include <bits/stdc++.h>
using namespace std;
// 速度分解 先求时间 再检验
// 输出了 nan ???
double n, x, v;
double ll, rr, vv, k=0;
int main()
{
scanf("%lf%lf%lf", &n, &x, &v);
for(int i=0; i<n; i++){
scanf("%lf%lf%lf", &ll, &rr, &vv);
k+=vv*(ll-rr);
}
double vy=k/x;
if(fabs(vy)>v) cout<<"Too hard"<<endl;
else{
double vx=sqrt(v*v-vy*vy);
double t=x/vx, flag=2*x/v;
if(t>flag) cout<<"Too hard"<<endl;
else printf("%.3lf\n", t);
}
//system("pause");
return 0;
}
L. Delayed Work
题意 : 装修房子 一个工人X元(与工作天数无关) 每天额外交P元,已知一个工人要干K天 ,M个工人则要干K/M天 给K, P, X, 求最小花费
思路 : 1将工人数从0到K枚举
#include <bits/stdc++.h>
using namespace std;
int main()
{
int k, p, x; scanf("%d%d%d", &k, &p, &x);
// 1个人要k天 每天*p元 每人共x元
// 天数向上取整 我在放屁
double ans=x*1.0+k*p*1.0;
// 枚举人数
for(int i=1; i<=100000; i++){
//int t=(k%i==0)?k/i:(k/i+1);
double m=i*x*1.0+k/(i*1.0)*p;
ans=min(ans, m);
}
printf("%.3lf\n", ans);
//system("pause");
return 0;
}
N. Latin Squares
题意 : 模拟 给出一个二维数组 两个判断条件:
1:第一行,第一列为1, 2, 3.。。。
2:每一行,每一列没有重复元素
思路 : 直接根据题意模拟即可 用set处理 可以判重
代码:
#include <bits/stdc++.h>
using namespace std;
// 先判断是否Latin
// 是的话再判断 第一行 第一列 是否递增
int main()
{
int n, flag=0; scanf("%d", &n);
set<char> s;
string a[40];
for(int i=0; i<n; i++) cin>>a[i];
// 先判断每一行
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) s.insert(a[i][j]);
if(s.size()!=n) { flag=1; break;}
}
// 再判断每一列
if(flag==0)
for(int j=0; j<n; j++){
for(int i=0; i<n; i++) s.insert(a[i][j]);
if(s.size()!=n) { flag==1; break;}
}
if(flag==1) { cout<<"No"<<endl; /*system("pause");*/ return 0;}
else{ // 是Latin
// 判断第一行
for(int j=0; j<n; j++) s.insert(a[0][j]);
int j=0;
for(set<char>::iterator it=s.begin(); it!=s.end(); it++){
if(*it!=a[0][j]) { flag=-1; break;}
else j++;
}
// 判断第一列
for(int i=0; i<n; i++) s.insert(a[i][0]);
int i=0;
for(set<char>::iterator it=s.begin(); it!=s.end(); it++){
if(*it!=a[i][0]) { flag=-1; break;}
else i++;
}
if(flag==-1) { cout<<"Not Reduced"<<endl; /*system("pause");*/ return 0;}
else { cout<<"Reduced"<<endl; /*system("pause");*/ return 0;}
}
}
O. Halfway
题意 : 给一个数n, 1+2+3+ n-1的和 sum, 求从n-1加到n时的值等于sum/2时,相加的值的数目
思路: 数值较大,遍历超时,故二分
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
LL n;
while(~scanf("%d", &n)){
LL l = 1,r = n;
LL sum = ((n-1) * n / 2 + 1)/2;
while(l <= r){
LL mid = (l+r) / 2;
LL cnt = 0;
cnt = (2*n - 1 - mid) * mid/2;
if(cnt - (n - mid) < sum && cnt >= sum){
cout << mid << endl;
break;
}
if(cnt < sum)
l = mid+1;
else
r = mid-1;
}
}
return 0;
}
P. Purple Rain
题意 : 给出一个只含有R与B的字符串 求R与B数目相差最多的连续字串的数目
思路 : 刚上来一顿暴力 不出意外的TLE了 将R当成1, B当成-1,求最大连续子列和
最大连续子列和:
从头开始相加,若到i和小于0了,则将开始位置设为i,不断更新sum的值
暴力代码:
#include<bits/stdc++.h>
using namespace std;
string s;
int main(){
cin >> s;
int sum = 0;
int len = s.size();
int a[len];
for(int i = 0; i < len; i++){
if(s[i] == 'B')
a[i] = -1;
else
a[i] = 1;
}
int st = 0, e = 0;
int i = 0, j = 0;
for(i = 0; i < len - 1; i++){
int su = 0;
for(j = i; j < len; j++){
su += a[j];
if(abs(su) > sum){
sum = abs(su);
st = i+1;
e = j+1;
}
}
}
cout << st << ' ' << e << endl;
}
时间1999ms
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define Maxn 100005
char s[Maxn];
int a[Maxn],n;
void DP(int &begin,int &end,int &sum) {// sum 表示最大子段和
sum = a[1];
int temp = a[1],cur = 1;
begin = end = 1;
for(int i=2; i<=n; i++){
if(temp + a[i] < a[i]){
temp = a[i];
cur = i;
}
else {
temp += a[i];
}
if(sum < temp){
sum = temp;
begin = cur;
end = i;
}
}
}
int main() {
scanf("%s",s + 1);
n = strlen(s + 1);
for(int i=1; i<=n; i++)
if(s[i] == 'R') a[i] = 1;
else a[i] = -1;
int begin1,end1,sum1 = 0;
DP(begin1,end1,sum1);
for(int i=1; i<=n; i++)
if(s[i] == 'R') a[i] = -1;
else a[i] = 1;
int begin2,end2,sum2 = 0;
DP(begin2,end2,sum2);
if(sum1 < sum2) { printf("%d %d\n",begin2,end2); }
else if(sum1 > sum2) { printf("%d %d\n",begin1,end1); }
else {// sum1 == sum2 的时候
if(begin1 < begin2) printf("%d %d\n",begin1,end1);
else if(begin1 == begin2) printf("%d %d\n",begin1,min(end1,end2));
else printf("%d %d\n",begin2,end2);
}
return 0;
}
Q. Unloaded Die
题意 : 给一个筛子,六个面1, 2, 3, 4, 5, 6,输入每个面的概率
求更改某个数使期望等于3.5 同时使数据变化尽可能小
思路 : 直接算 改概率最大的那个数数据变化最小
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
double a[7], ans = 0;
for(int i = 1; i < 7; i++){
cin >> a[i];
ans += a[i] * i;
}
sort(a+1, a+7);
printf("%.3f",fabs(ans-3.5) / a[6]);
return 0;
}