第一题 小码哥配速问题
#include<bits/stdc++.h>
using namespace std;
int num(char c){
return c -'0';
}
int main( )
{
char t[10];
int x;
int distance = 0,time=0;
while(scanf("%d",&x)!=EOF){
scanf("%s",t);
time += (num(t[0]) * 10 +num(t[1])) * 60 + num(t[3])* 10 +num(t[4]);
distance += x;
}
int ans =time *1000 / distance;
cout << ans /600 << ans / 60 % 10 << ":" << ans % 60 /10 << ans %10;
return 0;
}
其中关键的是,如何判断输入结束,在输入结束后,读取的末尾是EOF,只需要判断是否为EOF就可以知道是不是输入结束了!
while(scanf("%d",&x)!=EOF)
第二题 白日梦Ⅰ
#include<bits/stdc++.h>
using namespace std;
int main( )
{
int n;
cin >> n;
double ans = 10;
int mx = 0; //枚举最大汇率,美元换成英镑
for (int i=1;i<=n;++i){
int x;
scanf("%d",&x);
ans = max(ans,10.*(mx /10000.) * (10000. / x)); //英镑换成美元10000. / x
mx = max(mx,x);//维护的是过去美元转英镑的最大汇率
}
printf("%.2lf\n",ans);
return 0;
记录mx -美元换英镑的最大值,尽可能的多换成英镑,然后找到转换成美元的最大值,即找到x的最小值 。ans记录了之前转换成英镑的最大值后,每天都做一个转换成美元的计算,求出最大值。
第三题 双回文串
#include<bits/stdc++.h>
using namespace std;
bool check(char str[], int l, int r){
int mid = (l + r)/2;
for (int i = l;i <= mid;i++)
if(str[i] != str[l+r-i])
return 0;
return 1;
}
int main( )
{
char str[1001];
scanf("%s",str);
int n = strlen(str);
bool flag = false;
for (int i =1;i<n;i++)
if(check(str,0,i-1) && check(str,i,n-1))
flag = true;
if(flag)
cout << "YES";
else
cout << "NO";
return 0;
}
第四题 甄别情报
#include<bits/stdc++.h>
using namespace std;
int main( )
{
int t;
cin >> t;
for (int i = 0;i <t;i++){
int atoA[27] = {0},Atoa[27] = {0};
char a[100],b[100];
cin >> a >> b;
int len = strlen(a);
bool flag = true;
for (int i=0;i<len;++i){
int ida = a[i]-'a'+ 1,idb = b[i] - 'A' +1;
if(atoA[ida]){
if (atoA[ida] != idb){
flag = false;
break;
}
} else
atoA[ida] = idb;
if (Atoa[idb]){
if(Atoa[idb] != ida){
flag = false;
break;}
}
else
Atoa[idb] = ida;
}
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
Atoa和atoA两个列表 进行对照,判断是否为11对应的关系
第五题 数组稳定度
先排序,试着删除最大值或者最小值,进行差值比较
#include<bits/stdc++.h>
using namespace std;
int main( )
{
int n,a[100000];
cin >> n;
for (int i=0;i<n;i++)
cin >> a[i];
sort(a,a+n);
int mx = a[n-1],mx2 = a[n-2];
int mn = a[0],mn2 = a[1];
int ans = min(mx-mn2,mx2-mn);
cout << ans << endl;
return 0;
}
第六题 MC0116 水往低处流
#include<bits/stdc++.h>
using namespace std;
int a[2000][2000],n;
bool check(int i,int j){
if(i >0 && a[i][j] < a[i-1][j]) return 0;
if(j >0 && a[i][j] < a[i][j-1]) return 0;
if(i < n - 1 && a[i][j] < a[i+1][j]) return 0;
if(j < n-1 && a[i][j] < a[i][j+1]) return 0;
return 1;
}
int main( )
{
int ret = 0;
cin >> n;
for (int i = 0; i < n;i++)
for (int j =0;j<n;j++)
cin >> a[i][j];
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
if(check(i,j))
ret++;
cout << ret;
return 0;
}
check 寻找最高点,只要周围的四个点的高度都没有它高,那么就需要浇水了,标记为1 。那么标记为1 的有多少个,就需要浇水多少次。
第七题 MC0117 五行能量
#include<bits/stdc++.h>
#define maxn 17
using namespace std;
int a[maxn][6],b[6]; //a 存储的五行石,b目标能量
int main(){
int n;
cin >> n;
for (int i =1;i <= n;++i)
cin >> a[i][1] >> a[i][2] >> a[i][3] >> a[i][4] >> a[i][5];
cin >> b[1] >> b[2] >> b[3] >> b[4] >> b[5];
for (int i =0;i<(1 << n); ++i){ //左移n位,相当于小于2的N次方 多少种方法1001=9
int s[6] = {0}; //结果
for (int k = 1;k <= n;++k) // 遍历最低位到最高位k=0
if(i & (1 << (k-1))) //第k位是否为1
for (int j =1;j<=5;++j) // 存储目标列的数值
s[j] += a[k][j];
bool flag = true;
for(int j = 1;j <= 5;++j)
if(s[j] != b[j])
flag = false;
if(flag){
for (int ii =1;ii<=n;ii++)
if(i & (1 << (ii-1)))
cout << ii << " ";
return 0;
}
}
}
其思想是,遍历所有方法,将2^(n-1)种方法全部遍历一边,最后一行为目标值,s为某方法的结果值,最后两者进行每列的数值比较,如果相等则flag=true,不相等,就flag=false,就继续遍历。其中将是否要哪个五行石,看作0-1处理,并且根据先后顺序,来看作2的位数,从低位到高位,正好满足题目要求字典序最小的方案。
第八题 MC0118折纸
#include<bits/stdc++.h>
using namespace std;
//每次反转,对应的边长就变为MAX(翻折过去的长度,原长度-翻折过去的长度)
int main( )
{
double a,b;
cin >> a >> b;
int q;
cin >> q;
for (int i = 1; i <= q; ++i){
char s;
cin >> s;
double xy;
cin >> xy;
if(s == 'L')
a = max(xy, a-xy);
else
b = max(xy, b-xy);
}
printf("%.2lf %.2lf",a,b);
return 0;
}
第九题 MC0119马走日
#include<bits/stdc++.h>
#define maxn 1010
using namespace std;
int tx[8] = {1, 1, -1, -1, 2, -2, 2, -2};
int ty[8] = {2, -2, 2, -2, 1, 1, -1, -1};
struct NODE{
int x, y;
};
int main( )
{
queue<NODE> q;
int dp[maxn][maxn];
memset(dp, -1, sizeof(dp));
int n;
cin >> n;
int a, b;
cin >> a >> b;
dp[a][b] = 0;
q.push((NODE){a, b});
// bfs算法
while(!q.empty()){
int x = q.front().x, y = q.front().y;
q.pop();
for(int i = 0;i < 8; ++i){
int nx = x + tx[i],ny = y + ty[i];
if(nx < 0 || nx > n || ny < 0 || ny > n)
continue;
if(dp[nx][ny] != -1)
continue;
dp[nx][ny] = dp[x][y] + 1;
q.push((NODE){nx, ny});
}
}
//dp数组上的值位最少到达的步数,如果是-1则无法到达
int q2;
cin >> q2;
for (int i = 1; i <= q2; i++ ){
int c,d;
cin >> c >> d;
cout << dp[c][d] <<endl;
}
return 0;
}
其中用到了BFS(宽度/广度优先搜索)系统性的展开,彻底的搜索整张图。其中dp数组就是全图遍历后的结果,图上是最少步数,如果是-1的话,就是无法到达了。
第十题 MC0120 码哥猜想
#include<bits/stdc++.h>
using namespace std;
int main( )
{
int ans;
for(int i=1; i <= 100; ++i){
int temp = i;
bool flag = true;
while(temp != 1){
if(temp & 1)
temp = temp * 5 - 1;
else
temp = temp / 2;
if(temp>1e7){
flag = false;
break;
}
}
if(flag) cout << i << " ";
}
return 0;
}
在计算机中,数据以补码的二进制存储的。
偶数的最低位一定是0。
奇数的最低位一定是1。
所以如果要判断这个数是奇数还是偶数,只需要用这个数按位与1就可以了。
如果结果为0,那么这个数就是偶数,如果结果为1,那么这个数就是奇数。