A – a+b的问题(T组输入)
#include <iostream>
using namespace std;
int a, b;
int main(){
int T; cin>>T;
while(T--){
cin>>a>>b; cout<<a+b<<endl;
}
return 0;
}
B – 图灵的密码
最简单粗暴的方法:
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
string s;
while(cin>>s){
cout<<'-';
for(int i=0;i<s.size();i++)
switch (s[i]){
case '0' : cout<<".-----"; break;
case '1' : cout<<"..----"; break;
case '2' : cout<<"...---"; break;
case '3' : cout<<"....--"; break;
case '4' : cout<<".....-"; break;
case '5' : cout<<"-....-"; break;
case '6' : cout<<"--...-"; break;
case '7' : cout<<"---..-"; break;
case '8' : cout<<"----.-"; break;
case '9' : cout<<"------"; break;
}
cout<<endl;
}
return 0;
}
或者
#include<cstdio>
main(){for(char f,*a="-----.....----";f=~getchar();printf(f+11?"-%.5s":"-\n",a+58+f));}
好孩子不要这么写。
超级好孩子可以写的比这个还短。
C – 绝对素数
会判素数就可以了。基本的语言基础。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool isPrime(int t) {
if(t < 2) return false;
if(t <= 3) return true;
for(int i = 2; i * i <= t; i++) {
if(t % i == 0) return false;
}
return true;
}
int reverse(int t) {
int q = 0;
while(t) {
q *= 10;
q += t % 10;
t /= 10;
}
return q;
}
void exec(int n) {
int t;
while(n--) {
cin>>t;
if(isPrime(t) && isPrime(reverse(t))) {
puts("1");
}else {
puts("0");
}
}
}
int main() {
for(int n; cin>>n; exec(n));
return 0;
}
D – 面朝大海 春暖花开 [ 数据加强版 ]
看数据范围:1 <= n, m <= 100000。
如果是朴素模拟(在这里就是写二重循环,时间复杂度O(n^2)),最坏的情况下需要操作1e10次,必T。(一般 1e8 就是极限了)
时间复杂度是什么?大O是什么?-> https://blog.csdn.net/so_geili/article/details/53353593
这个题,实际上仍然可以用模拟来做,但是肯定不能用for循环++来模拟了,我们可以用计算的方法。
对于一组最终在[ l , r ]上查询的数据,一次在[c , d] 上的区间种花,有4种情况会出现:
l<=c && d<=r // 全部在[l,r]内 c<l && r<d // 完全包含[l,r] d<l || c>d // 完全没用 !(d<l || c>d) && !(l<=c && d<=r) //部分包含
(画画图就知道了)
然后计算端点值的差即可。
// 1.50M 28ms
#include <cstdio>
const int N = 100000;
int l[N], r[N];
int main() {
int n, m;
while(~scanf("%d %d", &n, &m)) {
int c, d, fl, fr, ans = 0;
for(int i = 0; i < m; i++) {
scanf("%d %d", &l[i], &r[i]);
}
scanf("%d %d", &fl, &fr);
for(int i = 0; i<m; i++) {
c = l[i];
d = r[i];
if(d<fl || c>fr) continue;
if(d>fr) d = fr;
if(c<fl) c = fl;
ans += d - c + 1;
}
printf("%d\n",ans);
}
return 0;
}
此算法空间复杂度、时间复杂度均为O(n),需要2n个int,离线算法。此算法适用于1350,上述代码也可AC1350。
也可以用前缀和做,快糙猛。
// 差分 scanf 1.45M 212ms
#include <cstdio>
#include <cstring>
int main() {
int n, m, t;
while(~scanf("%d %d %d", &n, &m, &t)) {
int *a = new int[n+2];
int c, d;
memset(a, 0, sizeof(int) * (n+2) );
while(m--)
scanf("%d %d", &c, &d),
a[c]+=1, a[d+1]-=1;
for(int i=1; i<=n; i++)
a[i] += a[i-1];
for(int i=1; i<=n; i++)
a[i] += a[i-1];
while(t--)
scanf("%d %d", &c, &d),
printf("%d\n",a[d]-a[c-1]);
delete[] a;
}
return 0;
}
也可以用st/bit做,不过没啥必要,小题大做了。还慢
不贴代码了,贴了你们也看不懂,看的懂的都不用贴。
E – 整数划分的空间优化问题
很简单的动态规划,二维优化为一维。
为什么不能朴素DFS?->有大量的重复计算,会超时。
动态规划是什么?-> 百度谷歌
如果语言基础还有不足,或基础算法还没有接触过,建议先跳过。
优化前可写为二维DP,优化后一维。原题有点卡常 傻逼行为,时间放宽至2s。
可参考 http://www.voidcn.com/article/p-nwdvvcjj-ng.html
不要在意这种C++写法。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <array>
using namespace std;
const int mod = 100000007;
const int N = 20100;
int main() {
array<unsigned, N> d;
d.fill(1);
for (int i = 2; i <= N; i++) {
for (int j = i; j <= N; j++) {
d[j] += d[j - i];
d[j] %= mod;
}
}
for (int n; cin >> n; cout << d[n] << endl);
return 0;
}
F – Relative Molecular Mass
trie,外加简单的一些类表达式处理。
无非繁琐了一点,难度实际上不高。
代码有点丑。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const int CM = 150;
struct Node {
double value;
Node* next[CM];
Node() { value = 0; memset(next, 0, sizeof(next));};
void construct(char* s, double value) {
if (!*s) { this->value = value; return; }
if (!next[*s]) { next[*s] = new Node();}
next[*s]->construct(s + 1, value);
}
} root, *cur;
char *x;
double solve() {
double ret = 0, val = 0;
for (; *x != 0 && *x != ')';) {
if (isalpha(*x)) {
if (cur->next[*x]) {
cur = cur->next[*x];
} else {
ret += val;
val = 0;
cur = root.next[*x];
}
if (cur->value) {
val = cur->value;
}
++x;
} else if (isdigit(*x)) {
int t = 0;
for (; isdigit(*x); ++x) {t *= 10; t += *x - '0';}
if (val) {
ret += val * t;
val = 0;
cur = &root;
} else {
ret += t * solve();
}
} else if (*x == '(') {
++x;
ret += val;
val = solve();
}
}
ret += val;
++x;
// cout << "RET " << ret << endl;
return ret;
}
int main() {
int n, k;
double v;
char s[300], t[200];
memset(root.next, 0, sizeof(root.next));
scanf("%d%d", &n, &k);
for (auto i = 0; i < n; i++) {
scanf("%s%lf", s, &v);
root.construct(s, v);
}
for (auto i = 0; i < k; i++) {
scanf("%s", t);
memset(s, 0, sizeof(s));
int j = 0, c = 0;
s[c++] = '(';
for (j = 0; t[j]; j++) {
if (t[j] == '.') {
s[c++] = ')';
s[c++] = '(';
} else {
s[c++] = t[j];
}
}
s[c] = ')';
cur = &root;
x = s;
auto ret = solve();
printf("%.lf\n", ret);
}
return 0;
}
本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.