这题打的时候时候打了个表,除了0、8,就没找出规律了,当时直觉是一定能通过有限的组合,在0-9之间组合出8的倍数,卡在找数的规律和如何组合数了 规律结论 只需要暴力判1-3位就行 官方题解给的是dp:https://codeforces.com/blog/entry/18329
int main() {
IOS;
string s;
cin >> s;
int len = s.size();
for (int i = 0; i < len; ++i){
if((s[i] - '0') % 8 == 0){
cout << "YES"<<endl<<s[i];
return 0;
}
for (int j = i + 1; j < len; ++j){
int temp = (s[i] - '0') * 10 + (s[j] - '0');
if(temp % 8 == 0){
cout << "YES"<<endl<<s[i]<<s[j];
return 0;
}
int t = temp;
for (int k = j + 1; k < len; ++k){
temp = t;
temp = temp * 10 + (s[k] - '0');
if(temp % 8 == 0){
cout << "YES"<<endl<<s[i]<<s[j]<<s[k];
return 0;
}
}
}
}
cout << "NO";
return 0;
}
板子题,板子不对,sad
#define ll long long
ll exgcd(ll a, ll b, ll &x, ll &y){
if(!b){
x = 1, y = 0;
return a;
}
ll d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main(){
ll a, b, c, x, y;
cin >> a >> b >> c;
ll d = exgcd(a, b, x, y);
if(c % d) {
cout << -1 << endl;
return 0;
}
x *= -c / d;
y *= -c / d;
cout << x << " " << y;
return 0;
}
map原来还可以这么用,大震惊 因为连续上升,所以直接用map存取数量最大的值,选取最终的数量最大的值进行倒推
#define ll long long
const int maxn = 2e5 + 5;
map<ll,ll> mp;
ll a[maxn];
int main(){
ll n;
cin >> n;
ll max_id = 0, max_num = 0;
for (int i = 1; i <= n; ++i){
cin >> a[i];
mp[a[i]] = max(mp[a[i]], mp[a[i] - 1] + 1);
}
for(auto w : mp){
if(max_id < w.second){
max_num = w.first;
max_id = w.second;
}
}
vector<ll> ans;
for (int i = n; i >= 1; --i){
if(a[i] == max_num){
ans.push_back(i);
--max_num;
}
}
cout << ans.size() << endl;
reverse(ans.begin(), ans.end());
for(auto w: ans){
cout << w << " ";
}
return 0;
}
很简单的题,自己写直接交了两发wa,还是队友写的 区间问题需要加强练习,老是对区间问题头疼(对啥都头疼 )
#define ll long long
int main(){
ll t;
cin >> t;
while(t--){
ll l, v, x, y;
cin >> l >> v >> x >> y;
if(x > y)
swap(x, y);
ll num = l / v;
ll temp = y / v - (x - 1) / v;
num -= temp;
cout << num << endl;
}
return 0;
}
队友独自写的,和另一个队友推不出来,我不明白她在说什么,结果是道A… 好神奇这道题!完全想不到!证明了我确实应该多刷这种思维题 n - t / x是中间选手的位置 谢谢万能群友的解答,刻烟入肺,我还想是不是什么需要记的结论
#define ll long long
int main(){
ll k;
cin >> k;
while(k--){
ll n, x, t;
cin >> n >> x >> t;
ll m = t / x;
ll ans = 0;
if(m >= n){
ans = (n * (n - 1)) / 2;
}
else {
ans = (n - m) * m + (m * (m - 1)) / 2;
}
cout << ans << endl;
}
return 0;
}
暴力模拟 谁懂,传参把数组换成变量就能过
int n, m, k;
int g[1100][1100];
int c[1100];
int row[1100];
int bfs(int st){
int x = st, y = 1;
while(y <= n){
if(g[y][x] == 1) {
g[y][x] = 2;
++x;
}
else if(g[y][x] == 2){
++y;
}
else if(g[y][x] == 3){
g[y][x] = 2;
--x;
}
}
return x;
}
int main(){
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
cin >> g[i][j];
}
}
for (int i = 1; i <= k; ++i){
int t;
cin >> t;
cout << bfs(t) << " ";
}
return 0;
}
当时看到题目我还想是不是题目会有什么玄机,但我觉得不可能这么直白吧 也是考虑了怎么拆,wa后没思路,队友猜测是不是什么规律,被否了,真是规律 两个结论任选其一就能得出答案: 1、n*m-n-m以上的数,n、m可以任意构成 2、1111等可由11、111构成
#include<iostream>
using namespace std;
#define ll long long
int main(){
int t;
cin >> t;
while(t--){
ll n;
cin >> n;
if(n % 11 == 0 || n % 111 == 0){
cout << "YES" << endl;
continue;
}
else {
bool flag = false;
while(n >= 11){
if(n % 11 == 0) {
flag = true;
break;
}
n -= 111;
}
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
return 0;
}
这道题用了set wa9,重新看了题是区间,感觉没法做;下来看了题解,好像还是很难的样子… 还有一种方法,但感觉比这个难 记下最后第一个重复的数,保证区间的扩大,取最小的区间确保能被覆盖完(没法说清楚,可能还不熟,待补)
#include<iostream>
#include<map>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
ll a[maxn];
map<ll, int> mp;
int main(){
int n;
cin >> n;
for (int i = 1; i <= n; ++i){
cin >> a[i];
}
int r = n;
while(r >= 1){
if(mp[a[r]] >= 1)
break;
++mp[a[r]];
--r;
}
int ans = INT_MAX;
for (int i = 1; i <= n; ++i){
ans = min(ans, r - i + 1);
++mp[a[i]];
while(mp[a[i]] >= 2 && r <= n ){
++r;
--mp[a[r]];
}
if(mp[a[i]] >= 2)
break;
}
cout << ans;
return 0;
}
麻了,暴力枚举每个点。没看到有人过,所以根本没考虑,但凡看下题 用数学下来还错了,麻中麻 还是有点难度,不知道怎么遍历菱形 等我深入学了计算几何吧字母太头疼了 挂几个题解在这里 A B C
推出来是二十六进制转十进制,但是我们三都不会大进制转小进制里面的细节,决定放弃 …题读错了还过了四个样例,我说呢;还错得没法改 对比了下思路,果然又复杂又乱orz 被卡吐了
sscanf需要返回值确定是否转化成功
int main() {
IOS;
int t;
cin >> t;
while(t--){
string s;
cin >> s;
int a, b;
char c[5], d;
if(sscanf(s.c_str(),"R%dC%d", &a, &b) == 2){
int ans[5], cnt = 0;
while(b != 0){
ans[cnt++] = (b - 1) % 26;
b = (b - 1) / 26;
}
for (int i = cnt - 1; i >= 0; --i){
printf("%c", ans[i] + 'A');
}
printf("%d\n", a);
}
else if(sscanf(s.c_str(),"%[A-Z]%d", &c, &a)){
int ans = 0;
char *p;
for(p = c, ans = 0; *p; p++){
ans = ans * 26, ans += *p - 'A' + 1;
}
printf("R%dC%d\n",a, ans);
}
}
return 0;
}
很明显的最短路,和之前写过的一个按权值搜的类似,还剩半小时,回忆+调出来的时间多半不够,放弃了 写倒是容易,调了半天,又发现思路错了… 摆了 下次认真补
int n, m, k, s;
int v[maxn];
vector<int> g[maxn];
vector<int> mp[maxn];
int dist[maxn][110];
bool vis[maxn];
int anss[maxn];
int temps[maxn];
void dij(int st) {
queue<int> q;
re(vis);
remax(temps);
for(int i = 1; i <= n; ++i){
if(v[i] == st) {
q.push(i);
temps[i] = 0;
}
}
while (!q.empty()) {
int id = q.front();
q.pop();
if (vis[id])
continue;
vis[id] = true;
for (auto w : g[id]) {
if (temps[w] > temps[id] + 1) {
temps[w] = temps[id] + 1;
q.push(w);
}
}
}
for(int i = 1; i <= n; ++i){
if(vis[i] != 0x3f3f3f3f){
dist[i][st] = temps[i];
}
}
}
int main() {
IOS;
remax(dist);
cin >> n >> m >> k >> s;
for (int i = 1; i <= n; ++i) {
cin >> v[i];
mp[v[i]].push_back(i);
}
for (int i = 1; i <= m; ++i) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
for (int i = 1; i <= k; ++i) {
dij(i);
}
for (int i = 1; i <= n; ++i){
sort(dist[i] + 1, dist[i] + k + 1);
int sum = 0;
for (int j = 1; j <= s; ++j){
sum += dist[i][j];
}
cout << sum << " ";
}
return 0;
}
推了一下,觉得是逆序对,被否了;考虑类似队列+栈的结合,没考虑出来,应该没多难啊 是t宝出的题! 官方题解:记录下每个每个车子出去的时间,如果后面的时间比前面的时间小,说明它超车了。因为先进先出,一定是递减顺序 pair排序加对比取最大值也可以
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], b[maxn], c[maxn],pos[maxn];
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; ++i){
cin >> a[i];
}
for (int i = 1; i <= n; ++i){
cin >> b[i];
}
for (int i = 1; i <= n; ++i){
pos[b[i]] = i;
}
for (int i = 1; i <= n; ++i){
c[i] = pos[a[i]];
}
int ans = 0;
int t = 0;
for (int i = 1; i <= n; ++i){
if(t > c[i])
++ans;
t = max(t, c[i]);
}
cout << ans;
return 0;
}
总之原理一样,但感觉这个更好理解(?)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 5;
pair<int, int> a[maxn];
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; ++i){
int t;
cin >> t;
a[t].first = i;
}
for (int i = 1; i <= n; ++i){
int t;
cin >> t;
a[t].second = i;
}
sort(a + 1, a + n + 1);
int ans = 0;
int t = 0;
for (int i = 1; i <= n; ++i){
if(t > a[i].second)
++ans;
t = max(t, a[i].second);
}
cout << ans;
return 0;
}
感觉像个分配的数学问题,卡在分配了,结果是贪心 一直wa4,是因为INT_MAX还是不够大,换成了0x3f3f3f3f3f3f3f3f过的 结合理解
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 5;
#define ll long long
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
ll prea[maxn], a[maxn], preb[maxn], prema[maxn], premb[maxn];
for (int i = 1; i <= n; ++i){
cin >> a[i];
if(i & 1){
if(i == 1)
prea[i] = prema[i] = a[i];
else
prema[i] = min(prema[i - 2], a[i]), prea[i] = prea[i - 2] + a[i];
}
else {
if(i == 2)
preb[i] = premb[i] = a[i];
else
premb[i] = min(premb[i - 2], a[i]), preb[i] = preb[i - 2] + a[i];
}
}
ll ans = 0x3f3f3f3f3f3f3f;
for (int i = 2; i <= n; ++i){
ll temp = 0, k = i / 2;
if(i & 1){
temp += prea[i] + (n - k - 1) * prema[i];
temp += preb[i - 1] + (n - k) * premb[i - 1];
}
else {
temp += prea[i - 1] + (n - k) * prema[i - 1];
temp += preb[i] + (n - k) * premb[i];
}
ans = min(ans, temp);
}
cout << ans << endl;
}
return 0;
}
怎么说呢,其他的题看了眼题号,暂不涉及哈
|