time:2019.12.01
水题不少,难题也有几个。
从1到1e6扫一遍,判断整除情况:若当前数在数组中且能整除,商也在数组中,则符合条件。注意特判完全平方的情况。
//#pragma GCC optimize(2)
#include
using namespace std;
const int maxn = 1e6+10;
int n, m, x, a[maxn];
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
memset(a, 0, sizeof(a));
for(int i=1; i<=n; i++)
{
cin>>x;
a[x]++;
}
bool flag = false;
if(m)
{
for(int i=1; i<=maxn-10; i++)
if(m%i==0 && a[i])
{
int tmp = m/i;
if(tmp > 1e6) continue;
if(tmp == i)
if(a[tmp] >= 2) flag = true;
if(tmp != i)
if(a[tmp] >= 1)
flag = true;
//cout<<"s"<
}
}
else
if(a[0]) flag = true;
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
奇-偶 = 奇,偶-奇 = 奇。
//#pragma GCC optimize(2)
#include
using namespace std;
int n, x, even=0, odd=0;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
long long sum = 0;
for(int i=1; i<=n; i++)
{
cin>>x;
sum += x;
if(x%2) odd++;
else even++;
}
if(sum%2)
{
if(even>1 || odd>1) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
else
{
if(odd>=1 && even>0) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
简单的字符转换操作。
//#pragma GCC optimize(2)
#include
using namespace std;
string str;
int n;
int main()
{
ios::sync_with_stdio(false);
while(cin>>str>>n)
{
for(int i=0; i<str.size(); i++)
if(str[i]>='a'+n && str[i]<='z') str[i] -= n;
else str[i] += 26-n;
cout<<str<<endl;
}
return 0;
}
按题意模拟即可。
//#pragma GCC optimize(2)
#include
using namespace std;
int n, m;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int a=1, b=0;
for(int i=1; i<=n; i++)
{
a *= 10;
b = b*10+9;
}
long long ans = 0;
for(int i=a/10; i<=b; i++)
{
int sum = 0;
int j = i;
while(j)
{
sum += j%10;
j /= 10;
}
if(sum == m) ans += i;
}
cout<<ans<<endl;
return 0;
}
//#pragma GCC optimize(2)
#include
using namespace std;
int t, x, y;
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>x>>y;
if(!x) cout<<"0 / 1"<<endl;
else
{
y += x;
x *= 4;
cout<<x/__gcd(x, y)<<" / "<<y/__gcd(x, y)<<endl;
}
}
return 0;
}
//#pragma GCC optimize(2)
#include
using namespace std;
int m, num;
int main()
{
ios::sync_with_stdio(false);
while(cin>>m)
{
int maxn = -0x3f3f3f3f;
while(m--)
{
cin>>num;
maxn = max(maxn, num);
}
cout<<maxn<<endl;
}
return 0;
}
这道题不筛也可以。
//#pragma GCC optimize(2)
#include
using namespace std;
const int maxn=1e3+1;
int cnt=0, max1=1e3, prime[maxn], rev[maxn];
bool flag[maxn];
void init()
{
fill(flag, flag+maxn, 1);
flag[0]=0;
flag[1]=0;
for(int i=2; i<=max1; i++)
{
if(flag[i])
{
prime[++cnt] = i;
rev[i] = cnt;
}
for(int j=1; j<=cnt&&prime[j]*i<=max1; j++)
{
flag[prime[j]*i] = 0;
if(!(i%prime[j])) break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
init();
int n;
while(cin>>n)
{
if(flag[n])
cout<<rev[n]<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
木桶效应,短板为决定方。
//#pragma GCC optimize(2)
#include
using namespace std;
int t, a, b, c, u, v, w;
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>u>>v>>w>>a>>b>>c;
int minn = 0x3f;
minn = min(minn, u/a);
minn = min(minn, v/b);
minn = min(minn, w/c);
cout<<minn<<endl;
}
return 0;
}
使用一个标记数组来标记出现过的数字。
进行死循环,如果标记数组里面已经是 1 了说明这个数出现过了,直接退出死循环,最终的数是 1 的话就输出循环的次数,不是的话输出最后这个数字。
//#pragma GCC optimize(2)
#include
using namespace std;
int n;
bool flag[1005];
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
memset(flag, 0, sizeof(flag));
flag[n] = 1;
int ans = 0;
while(n != 1)
{
int cnt = 0;
while(n)
{
int tmp = n%10;
cnt += tmp*tmp;
n /= 10;
}
n = cnt;
if(!flag[n])
{
flag[n] = 1;
ans++;
}
else
{
ans = n;
break;
}
}
cout<<ans<<endl;
}
return 0;
}
这真是道大模拟。校赛没做出来,补题的时候卡了一宿。卡就卡在改变数字后没有重新计数。
引用下题解文档的原话:
典型的模拟题,没什么太多可说的,按照题意枚举即可,看主代码手的手速吧(笑)。虽然算不上大模拟,但是还是有几个细节需要注意的,我来说一说这些细节。
- 有个彩蛋,是第 11 条的上述规则改动超过 8 条,也就是说第 11 个条件是前 10 个条件触发至少 9 个才会触发的,首先 7 与 8 一定是互斥的,其次我们可以发现 3 和 9 也是互斥的,所以第 11 个条件一定不会触发,如果发现不了这一点要多写一个唯一分解定理增添不少码量
- 我们很容易习惯性认为进行完规则 12 一定会进行规则 13,然而规则 12 中最后一次改变得分的规则有可能是规则 9,再进行完规则 9 后手牌点数会发生变化导致不一定再保证还有点数 2 的牌所以规则 13 要再次判断一下
- 规则 12 中说的上次改变得分的规则,不是上次执行的规则,比如你上次执行了 10,但是你手上没有 A,那么规则 10 没有改变你的得分,这样规则 10 就不是上次改变得分的规则
注意到这三点,码的还没有错误的话应该就能 ac 啦。
//#pragma GCC optimize(2)
#include
using namespace std;
string po[5];
int _first[5], huase[5], pai[15];
int red=0, black=0, _last, minn=0x3f3f3f3f;
long long sum = 0;
long long five(long long n) // 规则5
{
long long m=0;
int i;
for(i=1; i*i<n; i++)
if(!(n%i)) m += (i+n/i);
if(i*i == n) m += i;
return m;
}
int main()
{
//ios::sync_with_stdio(false);
for(int i=0; i<5; i++)
cin>>po[i];
for(int i=0; i<5; i++)
{
if(po[i].size() == 3) _first[i] = 10;
else if(po[i][0]>='2' && po[i][0]<='9') _first[i] = po[i][0]-'0';
else _first[i] = 10;
minn = min(minn, _first[i]);
sum += _first[i]; // 初始得分
// D方块 H红桃 C梅花 S黑桃
if(po[i][po[i].size()-1]=='D' || po[i][po[i].size()-1]=='H') red++;
else black++;
if(po[i][po[i].size()-1] == 'D') huase[0]++;
if(po[i][po[i].size()-1] == 'H') huase[1]++;
if(po[i][po[i].size()-1] == 'C') huase[2]++;
if(po[i][po[i].size()-1] == 'S') huase[3]++;
}
for(int i=0; i<5; i++)
{
if(po[i][0]>='2' && po[i][0]<='9') pai[po[i][0]-'0']++;
else if(po[i][0] == '1') pai[10]++;
else if(po[i][0] == 'J') pai[11]++;
else if(po[i][0] == 'Q') pai[12]++;
else if(po[i][0] == 'K') pai[13]++;
else if(po[i][0] == 'A') pai[14]++;
}
sum++;
sum += pai[11]*_first[0]; // 规则1
sum *= 2; // 规则2
if(huase[0] && huase[1] && huase[2] && huase[3]) sum *= 2; // 规则3
sum += abs(black-red); //规则4
if(!(sum%2)) sum += five(sum); // 规则5
//sum *= 2;
if(pai[7] == 4) sum -= 121; // 规则6
if(sum >= 0) // 规则7
{
sum += minn;
_last = 7;
}
if(sum < 0) // 规则8
{
sum *= (-1);
_last = 8;
}
if(huase[0] >= 3) // 规则9
{
sum++;
for(int i=0; i<5; i++)
{
if(po[i][0] == '2') po[i][0] = '5';
else if(po[i][0] == '5') po[i][0] = '2';
else if(po[i][0] == '6') po[i][0] = '9';
else if(po[i][0] == '9') po[i][0] = '6';
}
_last = 9;
// 牌计数改变
swap(pai[2], pai[5]);
swap(pai[6], pai[9]);
}
bool shunzi = 0;
for(int i=2; i<=10; i++)
if(pai[i] && pai[i+1] && pai[i+2] && pai[i+3] && pai[i+4])
{
shunzi = 1;
//break;
}
if(shunzi && pai[14]) // 规则10
{
sum += 5*pai[14];
_last = 10;
}
// 规则11不可能实现
if(pai[2]) // 规则12
{ // 跳转到上次改变得分的规则
if(_last == 7)
{
minn = 0x3f3f3f3f;
for(int i=0; i<5; i++)
{
if(po[i].size() == 3) _first[i] = 10;
else if(po[i][0]>='2' && po[i][0]<='9') _first[i] = po[i][0]-'0';
else _first[i] = 10;
minn = min(minn, _first[i]);
}
sum += minn;
}
if(_last == 8)
if(sum < 0) sum *= (-1);
if(_last == 9)
{
sum++;
for(int i=0; i<5; i++)
{
if(po[i][0] == '2') po[i][0] = '5';
else if(po[i][0] == '5') po[i][0] = '2';
else if(po[i][0] == '6') po[i][0] = '9';
else if(po[i][0] == '9') po[i][0] = '6';
}
}
if(_last == 10) sum += 5*pai[14];
}
bool after_change_2 = 0;
for(int i=0; i<5; i++)
if(po[i][0] == '2')
{
after_change_2 = 1;
//break;
}
if(after_change_2) sum *= 2;
cout<<sum<<endl;
return 0;
}
gls还是钛镪了。
还是那句话,gls钛镪了。
对于每只鸽鸽,只有最后一次 1 操作是决定性的,在此之前的操作都不会影响最终结果。我们可以分别对每只鸽鸽记一下最后一次操作 1 的时间,再对操作 2 求一下最大后缀。
对于每只鸽鸽,最终答案即为:
max(最后一次操作 1 的值,在最后一次 1 操作之后所有操作 2 的最大值)
这样可以在 O(n + q)的复杂度内实现。
//#pragma GCC optimize(2)
#include
using namespace std;
const int maxn = 2e5+5;
int n, q, a[maxn], change[maxn], p[maxn], maxx[maxn];
int main()
{
//ios::sync_with_stdio(false);
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];
cin>>q;
for(int i=1; i<=q; i++)
{
int op, x, y;
cin>>op;
if(op == 1)
{
cin>>x>>y;
change[x] = y;
p[x] = i;
}
else cin>>maxx[i];
}
for(int i=q-1; i>=1; i--)
maxx[i] = max(maxx[i], maxx[i+1]);
for(int i=1; i<=n; i++)
{
if(i>1) cout<<" ";
if(p[i]) cout<<max(change[i], maxx[p[i]]);
else cout<<max(maxx[1], a[i]);
}
return 0;
}
递推,注意long long。
//#pragma GCC optimize(2)
#include
using namespace std;
int a, b;
long long maze[55];
int main()
{
ios::sync_with_stdio(false);
maze[1] = 1;
maze[2] = 2;
for(int i=3; i<=54; i++)
maze[i] = maze[i-1]+maze[i-2];
while(cin>>b>>a)
cout<<maze[a-b]<<endl;
return 0;
}