记录一下这几天的题目
C - 极难的问题
那年一个菊苣问了asuka几个问题,把asuka花式吊打。
asuka思考了一下,不能光我一个人被吊打啊,于是他决定把这个题出出来。
如果一个数字中含有4或者7,那么这个数字就是不好看的,因为4明显不ok,而7的横折的弧度不太符合黄金分割,当然这个理由是我瞎编的。
那么问题来了,第n个好看的数字是多少呢?
Input
第一行一个t t<=10000 代表数据组数
每组的第一行一个n 1<=n<=1e9意义如题面。
Output
对于每一组输出一个x代表第n个好看的数字
Sample Input
2
1
7
Sample Output
1
9
思维题,就当作是八进制来看就行
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
char a[8]={'0','1','2','3','5','6','8','9'};
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n;
cin>>n;
string s = "";
while(n){
s = a[n%8] + s;
n /= 8;
}
cout<<s<<endl;
}
return 0;
}
D - 算法实力
一开始,一个人的算法实力是1,当他学会了一个难度值为x的算法的时候,因为两个算法是会产生灵感的,他的实力将变成之前的x倍。
现在alaikesitasa的算法实力是n,他说自己一直都在学同一种难度的算法并且学会了两个或更多,他说的是不是有可能是真的呢?
一个人学完算法之后实力一定会上升。
Input
第一行一个t t<=100代表数据组数
每一组一个n n<=1000000000 代表alaikesitasa的算法实力。
Output
对于每一组输出一个yes或者no代表alaikesitasa说的有没有可能是真的
Sample Input
3
2
3
4
Sample Output
no
no
yes
题目不难理解,就是判断一个数字能否开平方或者n次方,n可以取(2-30),最多30次方
这个其实也好办,就是将这个数先开n次方根再进行乘n次,判断前后是否一致即可
注意精度问题就好
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--){
long long n;
int f = 1;
cin>>n;
for(int i=2;i<=30;i++){
double x = pow(n*1.0,1.0/i);
long long sum = 1;
int num = x + 0.5;
for(int j=1;j<=i;j++){
sum *= num;
}
if(sum == n){
cout<<"yes"<<endl;
f = 0;
break;
}
}
if(f == 1)
cout<<"no"<<endl;
}
return 0;
}
E - 相同的不相同的字符串
研究证明,汉的字阅读序顺是不会影响你明白这句话的意思的。
但是如果顺序差的太多也是会影响的,比如汉阅读顺的序字你就看不懂什么意思了。
那么多少算多呢?科学家芦苇给出证明,当两个字符串中,如果A中的每一个字符的位置和在B中的同样的字符的位置的距离绝对值小于m,并且一一对应,那么就不会影响到阅读顺序。
也就是说如果把B重排可以得到A,那么B中的每一个字符的位置离A中的对应位置应小于等于m。
对于每一组字符串,判断B字符串还能不能读出A的意思。
Input
第一行一个t t<=7 代表数据组数
对于每一组,第一行一个m,意义如题意。 m <= 100
第二行一个字符串A len(A) <= 100000。
第二行一个字符串B len(A) == len(B)。
字符串都是英文小写字母。
Output
对于每一组输出一行yes或no代表B能不能读出A的意思。
Sample Input
2
0
ab
ba
1
ab
ba
Sample Output
no
yes
题目大意就不说了,一看就懂
直接进行模拟一下就好了
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
int vis[1000005];
int main()
{
int T;
scanf("%d",&T);
while(T--){
int k,f = 0;
cin>>k;
string a,b;
cin>>a;
cin>>b;
memset(vis,0,sizeof(vis));
int n = a.size();
for(int i=0;i<n;i++){
int x = i - k < 0 ? 0 : i - k;
int y = i + k > n ? n : i + k;
f = 0;
for(int j=x;j<=y;j++){
if(a[j] == b[i] && !vis[j]){
f = 1;
vis[j] = 1;
break;
}
}
if(f == 0)
break;
}
if(f == 1)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
F - 方方正正
现在有一块n*m的矩形,上面每一格都有一个小写字母。
如果一个子矩阵的四个角上的小写字母都是一样的,那么就可以摆一个魔法阵出来。
那么可以摆多少个魔法阵呢?
Input
第一行一个t t<=100 代表数据组数
每一组的第一行有两个数字n和m n,m<=100 代表矩形的行和列。
接下来的n行每行有一个长m的字符串,它们代表这个矩形
Output
对于每一组输出一个值代表可以构成的魔法阵的个数。
Sample Input
1
2 2
aa
aa
Sample Output
1
题目意思就是求四个角都是一样的字符的个数,直接暴力
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--){
int n,m;
scanf("%d %d",&n,&m);
getchar();
char a[105][105];
long long sum = 0;
for(int i=1;i<=n;i++)
cin.getline(a[i] + 1,m + 1,'\n');
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
for(int k=i+1;k<=n;k++){
if(a[i][j] == a[k][j]){
for (int l=j+1;l<=m;l++) {
if (a[i][j] == a[k][l] && a[i][j] == a[i][l])
sum++;
}
}
}
}
}
printf("%lld\n",sum);
}
return 0;
}
A - SUM
Calculate
MOD 1,000,000,007.(1≤n≤1e5, 1≤d≤1e9)
Input
The first line is an integer t(1≤t≤100), which is the number of test cases.
Then t lines follow. Each line contains two numbers n and d.
Output
T lines, which are the answers.
Sample Output
3
2 3
3 2
4 1
Sample Output
9
14
10
直接快速幂即可
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
long long mod = 1e9 + 7;
long long qpow(long long a,long long n){
long long re = 1;
while(n){
if(n & 1)
re = (re * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return re % mod;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
long long n,m;
scanf("%lld %lld",&n,&m);
long long sum = 1;
for(int i=2;i<=n;i++){
sum = (sum + qpow(i,m)) % mod;
}
printf("%lld\n",sum % mod);
}
return 0;
}
D - 小C的问题
小C是一个可爱的女孩,她特别喜欢世界上最稳定的图形:三角形。有一天她得到了n根木棍,她把这些木棍随意的摆放成一行。小K来和小C玩,他发现了这排木棍,突然想知道在一段区间[l,r]之间的木棍(即第L根到第R根木棍)是否可以组成一个三角形,小C表示她不会,所以请你帮忙。
Input
数据只有一组。
第一行只有一个数字N,代表一共有N根木棍,N<=100000。
第二行为N个数,代表每根木棍的长度。每根木棍的大小不超过1e18。
第三行为一个数字Q,代表询问数目,Q<=100000。
接下来的Q行,每一行有两个数字L和R,代表询问的区间。其中L和R满足1<=L<=R<=N。
Output
对于每个询问,如果可以组成三角形输出”Yes”,否则输出”No”(不需要加引号)。
Sample Input
5
3 1 2 4 5
2
1 3
1 5
Sample Output
No
Yes
就是给你一组数据,再给你一个范围,求这个范围中的数据能否构成三角形
其实范围大到一定程度就一定能构成三角形了,总所周知斐波拉契的数肯定是不能组成三角形的
而且斐波拉契数到第100多项的时候就已经超过10^18了,所以超过150都是yes,否则暴力就好了
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
long long a[100005],b[100005];
int main(){
int n,m;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d %d",&l,&r);
if(r - l + 1 < 3){
printf("No\n");
continue;
}
if(r - l + 1 > 150){
printf("Yes\n");
continue;
}
int k = 0,f = 1;
for(int i = l - 1;i < r;i++)
b[k++] = a[i];
sort(b,b+k);
for(int i=2;i<k;i++){
if(b[i] < b[i-1] + b[i-2]){
f = 0;
cout<<"Yes"<<endl;
break;
}
}
if(f == 1)
cout<<"No"<<endl;
}
return 0;
}
计算斐波拉契
/*int main(){
long long f[1000];
f[0] = 1;
f[1] = 1;
f[2] = 2;
int x = 0;
for(int i=2;f[i] < 1e18;i++){
f[i] = f[i-1] + f[i-2];
//cout<<f[i]<<" ";
x = i;
}
cout<<x<<endl;
return 0;
}*/
I - 小H的问题
小H是一个可爱的女孩,她特别喜欢看推特(tweeter)。有一天她得到了某位用户的一些推特消息,想从中提取出这个用户在这些消息中@了哪些人。但是这些消息太长了,她想请你来帮她完成这个任务。
每条消息中只会包含ASCII编码中的可见字符与空格。
推特中用户名的定义为一个长度大于0的字符串,且字符串中只包括数字0-9,英文字符a-z与A-Z,’-’与’_’。用户名区分大小写。
对@一个人的判定方式为:在消息中出现了”@username”,其中username为一个用户名,且为’@’后面所能匹配到最长的用户名。如”@TOM”,只能得到用户名TOM而不能得到用户名TO。同时’@’前面不能是一个合法的用户名字符,我们以此排除所有的邮箱信息。如”x@qq.com”我们不会提取出用户名,但”.@qq.com”我们要从中提取出”qq”。
Input
输入数据第一行为T,代表数据组数。(T<=5)
对于每组数据,第一行为n,代表推特消息数。接下来的n行中,每一行有一条长度小于140的推特消息。(n<=5)
Output
对于每组数据,第一行为k,代表n条消息中共@了多少个人(若同一个人被@了不止一次,则我们只记录一次)。接下来的k行中,每一行输出一个被@的用户名,k个用户名按照字典序排序。
Sample Input
2
5
@all, wish you have a nice contest~~~
Good Luck with you, @Contestant, @HUST!
Have Fun! :-) @All
Competition Topics By @HIT-CCPC
All Copyright Reserved @CCPC2018, @HIT-CCPC
4
HIT@CCPC
@HUST
@HIT-CCPC
@CCPC2018
Sample Output
6
All
CCPC2018
Contestant
HIT-CCPC
HUST
all
3
CCPC2018
HIT-CCPC
HUST
直接模拟即可,注意细节问题就好了
AC代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
vector<string>v;
int main()
{
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
getchar();
while (n--)
{
string s;
getline(cin, s);
for (int i = 0; i<s.size(); i++)
{
if (s[i] == '@')
{
string str = "";
if (i != 0 && ((s[i - 1] >= 'A'&&s[i - 1] <= 'Z') || (s[i - 1] >= 'a'&&s[i - 1] <= 'z') || (s[i - 1] >= '0'&&s[i - 1] <= '9') || s[i - 1] == '-' || s[i - 1] == '_'))
continue;
for (int j = i + 1;j<s.size(); j++)
{
if ((s[j] >= 'A'&&s[j] <= 'Z') || (s[j] >= 'a'&&s[j] <= 'z') || (s[j] >= '0'&&s[j] <= '9') || s[j] == '-' || s[j] == '_')
str += s[j];
else
break;
}
if (str != "" && find(v.begin(),v.end(),str) == v.end())
{
v.push_back(str);
}
}
}
}
cout << v.size() << endl;
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); i++)
cout << v[i] << endl;
v.clear();
}
return 0;
}