A-跳台阶
#include <iostream>
#include <stdio.h>
using namespace std;
long long f[50];
void fun() {
f[1] = 1;
long long sum = f[1];
for(int i = 2; i <= 30; i++) {
f[i] = sum+1;
sum += f[i];
}
}
int main() {
int n,t;
fun();
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
printf("%lld\n",f[n]);
}
return 0;
}
B-跳一跳,很简单的(待补)
C-平分游戏
/***********************************************************
Date 2018/3/28 15:27
Author Ms. Wen
解题思路:
参考他人思路:https://blog.csdn.net/hnust_Derker/article/details/79684711
*************************************************************/
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long ll;
const int maxn = 1000000+10;
ll a[maxn],b[maxn],c[maxn];
int vis[maxn];
ll cal(ll n,ll aver) {
c[0] = 0;
for(int i = 1; i < n; i++) {
c[i] = c[i-1] + b[i] - aver;
}
sort(c,c+n);
ll temp = c[n/2];
ll ans = 0;
for(int i = 0; i < n; i++) {
ans += abs(temp-c[i]);
}
return ans;
}
int main() {
ll n,k,sum;
while(~scanf("%lld%lld",&n,&k)) {
//隔k个人,则编号要跳k+1个
k++;
sum = 0;
for(int i = 0; i < n; i++) {
scanf("%lld",&a[i]);
sum += a[i];
}
//无法对n各人平分
if(sum%n) {
puts("gg");
}
//不是所有人都能参加游戏
else if(k >= n) {
//此时必须保证所有人已经是平均值
bool flag = true;
for(int i = 0; i < n; i++) {
if(a[i] != sum/n) {
puts("gg");
flag = false;
break;
}
}
if(flag) {
printf("0\n");
}
}
else {
ll cnt,temp,ans=0;
bool flag = true;
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++) {
if(vis[i]==0) {
temp = 0;
cnt = 1;
for(int j = i; vis[j]==0 ; j = (j+k)%n) {
b[cnt++] = a[j];
temp += a[j];
vis[j] = 1;
}
//无法整除
cnt--;
if(temp%cnt) {
puts("gg");
flag = false;
break;
} //可以整除,但是无法和总体平均值相同。
if(temp/cnt != sum/n) {
puts("gg");
flag = false;
break;
}
ans += cal(cnt,sum/n);
}
}
if(flag) {
printf("%lld\n",ans);
}
}
}
return 0;
}
D-psd面试
/**********************************************************
Date 2018-03-25 09:52:10
Author Ms. Wen
解题思路:
比赛完了,看了别人的代码终于明白题目意思了,题目给出的
串是可以删除任意字符的,因此求区间i-j中最多有多少成对的
字符,所谓成对即相等。
*********************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 1500;
char str[maxn];
int dp[maxn][maxn]; //dp[i][j]i到j区间的字符有多少个成对的。
int main() {
while(~scanf("%s",str)) {
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i]>='A' && str[i]<='Z') {
str[i] += 32;
}
}
memset(dp,0,sizeof(dp));
for(int i = len-1; i >= 0; i--) {
dp[i][i] = 1;
for(int j = i+1; j < len; j++) {
if(str[i] == str[j]) dp[i][j] = max(dp[i][j],dp[i+1][j-1]+2);
else dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
}
}
printf("%d\n",len-dp[0][len-1]);
}
return 0;
}
E-回旋星空
/***********************************************************
Date 2018/3/27 15:08
Author Ms. Wen
解题思路:枚举每个点,对于点i,使用map统计距点i距离为dist的点有
多少个,然后可以从里面任意选两个点,比如n个点,任意选2个点,共
n*(n-1)/2,又因为两个点可以有先后顺序,则方案数是n*(n-1)。
*************************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
const int maxn = 1e3+10;
int x[maxn],y[maxn];
int calDist(int i,int j) {
return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
int main() {
int t,n,dist;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%d%d",&x[i],&y[i]);
}
int ans = 0,num;
for(int i = 1; i <= n; i++) {
map<int,int>m;
map<int,int>::iterator it;
for(int j = 1; j <= n; j++) {
dist = calDist(i,j);
m[dist]++;
}
for(it = m.begin(); it != m.end(); it++) {
if(it->second >= 2) {
num = it->second;
ans = ans + num*(num-1);
}
}
}
if(ans == 0) {
printf("WA\n");
}
else {
printf("%d\n",ans);
}
}
return 0;
}
F-等式
/***********************************************************
Date 2018/3/27
Author Ms. Wen
解题思路:考察数论中的唯一分解定理。但是关键是对式子做变换。
设x=n+a,y=n+b。 1/x+1/y=n 可以化成n*n = a*b。化成这样后,只要
知道n*n的因子个数,就可以得到答案。
求解因子,根据基础数论知识可知任何正整数n都可以表示成如下形式:
n = p1^e1*p2^e2...pn^en (其中p1,p2,...,pn都是素数)。
其因子个数就是:(e1+1)*(e2+1)*...*(en+1),则
n*n = p1^(2*e1)*p2^(2*e2)*...p3^(2*e3)。
其因子个数就是:(2*e1+1)*(2*e2+1)*...*(2*en+1)。
因为x<=y,则需要a<=b,最后因子数除2加1就是答案。
主要就是变换难想,比赛的时候也没想出来。
*************************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main() {
int t,n,cnt;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
long long ans = 1;
for(int i = 2; i<=sqrt(n); i++) {
if(n%i == 0) {
cnt = 0;
while(n%i==0) {
cnt++;
n = n/i;
}
ans = ans*(2*cnt+1);
}
}
//除过后n是素数的情况
if(n != 1) {
ans = ans*3;
}
printf("%lld\n",(ans+1)/2);
}
return 0;
}
G-旋转矩阵
/**********************************************************
Date 2018-03-25 10:43:38
Author Ms. Wen
解题思路:
设左转为加1,右转是减1,左转右转可以抵消,先算出最终是像某个方向
转了num次。然后对4取余。
1.num%4是0,原样输出。
2.num%4是2,按行从大到小,列从大到小打出。
3.num%4==3&&是左转,num%4==1&&是右转,左转三次和右转一次相同。
4.左转一次和右转三次的情况。
只要捋清楚打印时的方向,就能弄对,这个为了更清楚,可以把图画到
纸上,这样拿纸去旋转要比脑子单纯想要可靠的多。
*********************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cmath>
using namespace std;
char Map[50][50];
char str[1005];
int n,m;
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
scanf(" %c",&Map[i][j]);
}
}
scanf("%s",str);
int cnt = 0;
for(int i = 0; i < (int)strlen(str); i++) {
if(str[i]=='L') {
cnt++;
}
else {
cnt--;
}
}
if(abs(cnt)%4 == 0) {
printf("%d %d\n",n,m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
printf("%c",Map[i][j]);
}
printf("\n");
}
}
else if(abs(cnt)%4 == 2) {
printf("%d %d\n",n,m);
for(int i = n; i > 0; i--) {
for(int j = m; j > 0; j--) {
printf("%c",Map[i][j]);
}
printf("\n");
}
}
else if((cnt>0&&cnt%4==3) || (cnt<0&&(abs(cnt)%4==1))){
//左转三次或右转一次。
printf("%d %d\n",m,n);
for(int i = 1; i <= m; i++) {
for(int j = n; j >= 1; j--) {
if(Map[j][i]=='-') printf("|");
else if(Map[j][i]=='|') printf("-");
else printf("%c",Map[j][i]);
}
printf("\n");
}
}
else {
printf("%d %d\n",m,n);
for(int i = m; i >= 1; i--) {
for(int j = 1; j <= n; j++) {
if(Map[j][i]=='-') printf("|");
else if(Map[j][i]=='|') printf("-");
else printf("%c",Map[j][i]);
}
printf("\n");
}
}
printf("\n");
}
return 0;
}
H-哲哲的疑惑(待补)
I-填空题
输出ac即可
J-强迫症的序列
/**********************************************************
Date 2018-03-24 16:32:02
Author Ms. Wen
解题思路:对数组从小到大排序,先让第二小不动,让最小往其上面并。
让后让第三小不变,让前两个往它身上并,一直这样考虑。
*********************************************************/
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 1e6+10;
long long a[maxn];
int main() {
int t,n;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%lld",&a[i]);
}
sort(a,a+n);
int cnt = 0;
a[cnt++] = a[0];
for(int i = 1; i < n; i++) {
if(a[i]!=a[i-1]) {
a[cnt++] = a[i];
}
}
long long sum = 0,tmp;
for(int i = 1; i < cnt; i++) {
tmp = a[i]+sum-a[i-1]; //前i-1个并到第i个需要多少次操作
a[i] = a[i] + sum; //更新高度
sum += tmp;
}
printf("%lld %lld\n",sum,a[cnt-1]);
}
return 0;
}
K-密码
/**********************************************************
Date 2018-03-24
Author Ms. Wen
解题思路:总结字符之间间隔的规律,注意一点,n = 1时,单独处理,
其他情况按照间隔规律处理。
*********************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 1e7;
char str[maxn];
char ans[maxn];
int main() {
int t,n;
scanf("%d",&t);
while(t--) {
scanf("%d ",&n);
gets(str);
if(n > 1) {
int cnt = 0;
int len = strlen(str);
int m = 2*n-2;
for(int i = 1; i <= len; i+=m) {
ans[cnt++] = str[i-1];
}
for(int i = 2; i <= n-1; i++) {
int tmp = 2*n-2*i;
for(int j = i; j <= len; j+=m) {
ans[cnt++] = str[j-1];
if(j+tmp <= len) {
ans[cnt++] = str[j+tmp-1];
}
}
}
for(int i = n; i <= len; i+=m) {
ans[cnt++] = str[i-1];
}
ans[cnt] = '\0';
puts(ans);
}
else {
puts(str);
}
}
return 0;
}
L-用来作弊的药水
/**********************************************************
Date 2018-03-24 14:16:28
Author Ms. Wen
解题思路:判断x^a = y^b 两边对y取对数,logy(x^a) = b
a * logy(x) = b ,但是C语言中没有以任意数为底的对数的计算,
C语言math函数中的log是默认以10为底的,所以需要判断。
a * log(x)/log(y) = b -> a*log(x) = b*log(y)
最终判断这个式子就可以了。
*********************************************************/
#include <stdio.h>
#include <math.h>
#define eps 1e-4
int main() {
int x,a,y,b,t;
scanf("%d",&t);
while(t--) {
scanf("%d%d%d%d",&x,&a,&y,&b);
double tmp1 = a*log(x);
double tmp2 = b*log(y);
if(fabs(tmp1-tmp2)<eps) {
printf("Yes\n");
}
else {
printf("No\n");
}
}
return 0;
}
本文精选了多项算法竞赛题目,并提供了详细的解题思路与代码实现,涵盖了数组操作、字符串处理、数学技巧及图形分析等多个方面。
524

被折叠的 条评论
为什么被折叠?



