https://codeforces.com/contest/898
A:
题意;
给出一个数字 ,四舍五入一下。
题解 :
四舍五入
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int main()
{
int n;
while(cin>>n)
{
if(n%10<=5) cout<<n-n%10<<endl;
else cout<< n-n%10+10 <<endl;
}
}
B
题意:
给出三个数字 N,A,B。
找到两个数字 x,y
xa+yb==n
题解;
使得n%a 的余数 依次增加a ,直到可以整除b为止
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int main()
{
int n,a,b;
while(cin>>n>>a>>b)
{
int mod=n%a;
int x=n/a,y=0;
while(mod&&x)
{
mod=(mod+a)%b;
x--;
}
if(mod==0) cout<<"YES"<<endl<<x<<' '<<(n-x*a)/b<<endl;
else cout<<"NO"<<endl;
}
}
C
前导0好烦啊。还要保留前导0 ,有毒。
#include<bits/stdc++.h>
using namespace std;
const long long maxn = 1e5 + 5;
map<string, long long > tag;
map<string, vector<string > > phone;
long long huan ( string &s )
{
long long ans = 0;
for ( int i = 0; s[i]; i++ )
ans = ans * 10 + s[i] - '0';
return ans;
}
bool cmp ( string &a, string &b )//引用可以降低空间损耗和时间。
{
long long x = huan ( a );
long long y = huan ( b );
if ( x != y )
return x > y;
else
return a.size() > b.size();
}
int main()
{
long long n;
while ( cin >> n )
{
string str, x;
long long m;
for ( long long i = 0; i < n; i++ )
{
cin >> str >> m;
for ( long long i = 0; i < m; i++ )
{
cin >> x;
phone[str].push_back ( x );
}
}
cout << phone.size() << endl;
for ( auto i = phone.begin(); i != phone.end(); i++ )
{
vector<string > &temp = i->second, pl;
sort ( temp.begin(), temp.end(), cmp );
cout << i->first << ' ';
tag.clear();
for ( long long j = 0; j < temp.size(); j++ )
{
string num = temp[j];
if ( !tag[num] )
{
string e;
for ( long long i = num.size() - 1; i >= 0; i-- )
{
e = num[i] + e;
tag[e] = 1;
}
pl.push_back ( num );
}
}
cout << pl.size() << ' ';
for ( long long j = 0; j < pl.size(); j++ )
cout << pl[j] << ' ';
cout << endl;
}
}
return 0;
}
程序员就要反复推敲代码已追求代码的极致。
D
一直在调边界- -
#include <bits/stdc++.h>
const int maxn = 2e5 + 5;
using std::cin;
int a[maxn];
std::queue<int > q;
int main()
{
int n, m, k;
while ( cin >> n >> m >> k )
{
for ( int i = 1; i <= n; i++ )
{
cin >> a[i];
}
std::sort(a+1,a+n+1);
int ans=0;
for(int i=1;i<=n;i++)
{
if(q.size()<k-1)
{
q.push(a[i]);
}
else if(q.size()&&a[i]-q.front()>m-1)
{
while(q.size()&&a[i]-q.front()>m-1 ) q.pop();
q.push(a[i]);
}
else
{
ans++;
}
//std::cout<<"asd "<<a[i]<<std::endl;
}
std::cout<<ans<< std::endl;
}
}
https://codeforces.com/contest/898/problem/E
题意:
每次可以让一个数字增加1,可以让一个数字减少1(当这个数字大于0的时候)
然后 ,要让一半的数字是平方数,另一半不是平方数,求最少的操作次数;
题解:
二分查找最近的平方数,按照差值排序
因为0想变成非平方数需要操作两次。所以 在寻找平方数的时候优先使用0;
最后求和。
#include <bits/stdc++.h>
const long long maxn=2e5+5;
using std::cin;
using std::cout;
using std::endl;
struct node
{
long long x,y,z;
}a[maxn];
bool cmp(node a,node b)
{
if(a.y!=b.y) return a.y<b.y;
else return a.z>b.z;
}
bool cmp1(node a,node b)
{
return a.z<b.z;
}
long long powe[maxn];
int main()
{
long long n;
for(long long i=0;i<=35000;i++) powe[i]=i*i;
while(cin>>n)
{
long long x,y;
for(long long i=0 ;i< n ; i++ )
{
cin >> a[i].x;
long long v=std::lower_bound(powe,powe+34000,a[i].x)-powe;
x=v,y=std::max((long long)0,v-1);
a[i].y=std::min( abs(powe[x]-a[i].x) ,abs(powe[y]-a[i].x) );
if(a[i].x==0) a[i].z=2;
else if(a[i].y==0) a[i].z=1;
else a[i].z=0;
}
std::sort(a,a+n,cmp);
long long ans=0;
for(long long i=0;i<n/2;i++)
{
ans+=a[i].y;
// cout<<ans<<' '<<a[i].x<<' '<<a[i].y<<' '<<a[i].z<<endl;
}
std::sort(a+n/2,a+n,cmp1);
// cout<<"xxxxxxxxxxxxx "<<endl;
for(long long i=n/2;i<n;i++)
{
ans+=a[i].z;
// cout<<ans<<' '<<a[i].x<<' '<<a[i].y<<' '<<a[i].z<<endl;
}
cout<<ans<<endl;
}
}
https://codeforces.com/contest/898/problem/F
题意:
给一个字符串s,
把字符串分成a+b=c的形式;
题解 :
首先可以知道,只需要枚举位置 去判断a+b==c 就可以了
其实大数可做,但是大数的每次判断是o(n) 加上枚举位置
复杂度为n^2
所以 将大数需要判断的地方改成字符串哈希
为了准确,用两个哈希表去判断。
知识点:字符串哈希。加法运算;
注意判断间隔点,a,b,c 都至少包含一位数,并且不存在前导0
#include <bits/stdc++.h>
using namespace std;
const long long base = 10;
const long long mod1 = 1e8 + 7, mod2 = 1e7 + 7;
const long long maxn = 1e6 + 5;
long long hash1[maxn], hash2[maxn], mu1[maxn], mu2[maxn];
string s;
void show ( long long x, long long y, long long z )
{
for ( int i = 0; i < x; i++ )
{
cout << s[i];
}
cout << "+";
for ( int i = x; i < y; i++ )
cout << s[i];
cout << "=";
for ( int i = y; s[i]; i++ )
cout << s[i];
cout << endl;
}
void check ( long long x, long long y, long long z )
{
long long a = ( hash1[x] + hash1[y] - hash1[x] * mu1[y - x] % mod1 + mod1 ) % mod1;
long long b = ( hash1[z] - hash1[y] * mu1[z - y] % mod1 + mod1 ) % mod1;
long long aa = ( hash2[x] + hash2[y] - hash2[x] * mu2[y - x] % mod2 + mod2 ) % mod2;
long long bb = ( hash2[z] - hash2[y] * mu2[z - y] % mod2 + mod2 ) % mod2;
if ( ( s[x] != '0' || y - x == 1 ) && ( s[y] != '0' || z - y > 1 ) || aa == 0 && bb == 0 )
if ( a == b && aa == bb && x && y > x && y < z )
{
// cout<<hash1[x]<<' '<<a<<' '<<b<<' '<<aa<<' '<<bb<<' '<<x<<' '<<y<<endl;
show ( x, y, z );
}
}
int main()
{
while ( cin >> s )
{
mu1[0] = mu2[0] = 1;
for ( long long i = 0; s[i]; i++ )
{
hash1[i + 1] = ( hash1[i] * base + s[i] - '0' ) % mod1;
hash2[i + 1] = ( hash2[i] * base + s[i] - '0' ) % mod2;
mu1[i + 1] = mu1[i] * 10 % mod1;
mu2[i + 1] = mu2[i] * 10 % mod2;
}
long long len = s.size();
long long pj = s.size() / 3;
for ( int j = 1; j < len - 1; j++ )
{
int y;
if ( ( len - j ) / 2 >= j )
y = ( len - j ) / 2;
else
y = len - j * 2;
if ( y >= 0 )
{
check ( j, j + y, len );
check ( j, j + y + 1, len );
check ( j, j + y - 1, len );
}
}
}
}