贴个比赛链接: icpc/acm/牛客周赛Round-56
一共六题,a了A~E五题,浅浅写一下这几题题解,以下是本场过题情况~
A题
思路分析
水题,直接过
代码实现
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<unordered_map>
#include<unordered_set>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
void solve()
{
int x,y,n;
cin >> x >> y >> n;
if(x + y <= n) cout << "YES" << endl;
else cout << "NO" << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t = 1;
while(t--) solve();
return 0;
}
B题
思路分析
这题出题人太搞了,小S和m个人一起,要注意“小S”也是人,所以折出来纸飞机的个数应该和(m+1)取最小值,蚌埠住了--比赛的时候wa了几发
代码实现
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<unordered_map>
#include<unordered_set>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
int a[N];
int sum = 0;
void solve()
{
int n,m,k;
cin >> n >> m >> k;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
int t = sum * 1.0 / k * 1.0;
if(t < m + 1) cout << t << endl;
else cout << m + 1 << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t = 1;
while(t--) solve();
return 0;
}
C题
思路分析
- 根据异或的性质来做,用1去异或上一个数n,如果n为奇数则得到n−1,否则我们会得到n + 1,由此我们发现,直接用1去异或就好了嘛,但考虑特殊的两个数,输入为1或1e9时,我们发现,用1去异或得到的两个数为0和1e9 + 1,不在我们要求的范围内,所以我们特判一下这两个数即可
- 直接在[1,1e9]范围内枚举i找出满足a ^ i = t 且i ^ t = a 的i 和 t 值,但要注意要求两个数都在[1,1e9]内,所以要对 t 加个条件判断
代码实现
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<unordered_map>
#include<unordered_set>
#define int long long
#define x first
#define y second
using namespace std;
const int N = 1e5 + 10;
void solve()
{
int a; cin >> a;
/* for(int i = 1; i <= 1e9; i++)
{
int t = a ^ i;
if(i ^ t == a && t >= 1 && t <= 1e9)
{
cout << i << " " << t << endl;
return;
}
} */
if(a == 1) cout << 2 << " " << 3 << endl;
else if(a == 1e9) cout << 999999999 << " " << 1023 << endl;
else cout << 1 << " " << (1 ^ a) << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t ;
cin >> t;
while(t--) solve();
return 0;
}
D题
思路分析
D题比较简单,先对一组数进行升序排序,我们知道当三角形的两条边之和小于等于最长的那条边的长度时则不能构成三角形,所以我们直接从前往后或者从后往前进行枚举,当发现连续三个边不能构成三角形时我们continue,否则更新最大值(从后遍历则直接输出),需要注意的地方就是本题不能开三重for循环,会超时,最多只能开二维
代码实现
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>
#define int long long//这题会爆int(2147483648),必须开long long
using namespace std;
const int N = 1e4 + 10;
int n;
int a[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
int sum1 = INT_MIN;
for(int i = 1; i <= n - 2; i++)
{
for(int j = i + 1; j <= n - 1; j++)
{
if(a[j + 1] >= a[i] + a[j]) continue;
sum1 = max(sum1 , (a[i] + a[j] + a[j + 1]));
}
}
if (sum1 == INT_MIN) cout << "-1" << endl;
else cout << sum1 << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) solve();
return 0;
}
/* #include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>
#define int long long
using namespace std;
const int N = 1e4 + 10;
int n;
int a[N];
int sum[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
int flag = 0;
for(int i = n; i >= 3; i--)
{
if(a[i - 1] + a[i - 2] > a[i])
{
flag = 1;
cout << a[i - 1] + a[i - 2] + a[i] << endl;
break;
}
}
if(!flag) cout << "-1" << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) solve();
return 0;
} */
E题
思路分析
E题就是一个小模拟,思想很简单,调了我好久好久,这题依旧要注意 t 在 10的5次方以内,如果我们还在while(t - -)里开for循环一定会超时,所以必须在输入的时候进行预处理,我们能发现时间可能跨天数,如果不跨天数我们将起始时间到终止时间这一段全部标记为开心时间即可(但是要在0.00--1.59以内),所以终止时间要和120取个最小值,如果跨天数,在一天中的有效区间就变成了00:00−结束时间和起始时间−23:59的并集,我们每次跟120做一次比较即可。
代码实现
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<unordered_map>
#include<unordered_set>
#define int long long
#define x first
#define y second
using namespace std;
int n,m;
const int N = 1e5 + 10;
vector<string> str(N);
vector<string> str1(N);
vector<string> str2(N);
int flag1,flag2,flag3 = 0;
int mt(string s)//计算分钟
{
int k = 0;
k = ((s[0] - '0') * 10 + (s[1] - '0')) * 60 + (s[3] - '0') * 10 + (s[4] - '0');
return k;
}
bool check1(string s,vector<int> &vis)
{
if(mt(s) < 120 && vis[mt(s)]) return true;
return false;
}
bool check2(string s1,string s2)//判断有没有迟到
{
int a,b;
a = mt(s1);
b = mt(s2);
if(a <= b) return true;
return false;
}
bool check3(string s,set<string> &hash)//判断是不是喜欢喝的奶茶
{
if(hash.count(s)) return true;
return false;
}
void solve()
{
vector<int> vis(150,0);//标记数组,记录每一分钟能否作为开心时间
set<string> hash;
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
cin >> str1[i] >> str2[i];
int c,d;
c = mt(str1[i]);
d = mt(str2[i]);
if(c >= d)
{
for(int i = 0; i < min(120ll,d); i++) vis[i] = 1;
for(int i = c; i <= 120; i++) vis[i] = 1;
}
else
{
for(int i = c; i <= min(120ll,d); i++) vis[i] = 1;
}
}
for(int i = 1; i <= m; i++)
{
cin >> str[i];
hash.insert(str[i]);
}
int q;
cin >> q ;
while(q -- )
{
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
string str3; cin >> str3;
string str4,str5; cin >> str4 >> str5;
string str6; cin >> str6;
if(check1(str3,vis)) flag1 = 1;
if(check2(str4,str5)) flag2 = 1;
if(check3(str6,hash)) flag3 = 1;
//cout << flag1 << " " << flag2 << " " << flag3 << endl;
if(flag1 == 1 && flag2 == 1 && flag3 == 1 ) cout << "Winner xqq" << endl;
else if(flag1 == 0) cout << "Loser xqq" << endl;
else cout << "Joker xqq" << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t = 1;
while(t--) solve();
return 0;
}
/* 由于有效区间只有00:00−1:59,我们直接把时间用分钟表示就好了,
开个标记数组记录每一分钟是否可以作为快乐时间,
唯一的小坑点就是如果起始时间大于结束时间,那说明这东西跨了一天,在一天中的有效区间就变成了0:00−结束时间
和起始时间−23:59的并集,我们每次跟120做一次比较即可 */
F题笔者暂时还没开,看通过人数也不是那么好做,正解好像是字符串哈希+二分,之后再看看吧~~~
拜拜~~